reactjs - e.preventDefault 阻止我使用 Enzyme 进行单元测试
问题描述
我有一个带有按钮的 reactJS 应用程序。
当用户按下按钮时,用户会在手机上获得验证码。
起初,当用户按下按钮时,表单会随机刷新,但我发现我必须使用
event.preventDefault();
停止按钮刷新。
所以在我的 onClick 处理程序中,我有以下结构。
代码 - const handleOnClick = async(event) => { event.preventDefault();
逻辑..(包括对后端 API 的异步调用)
}
但是,我的问题是,当我使用 Enzyme 创建单元测试时,该函数在“preventDefault()”中返回并且从不执行逻辑。
在这种情况下是否有测试单元测试?
import React, {useState} from 'react';
import TextField from "@material-ui/core/TextField";
import Grid from "@material-ui/core/Grid";
import {
isInputNumeric,
processKoreaCellphone
} from '../../../../api/auth/authUtils';
import {requestMobileVerificationCode} from "../../../../api/auth/authApiConsumer";
import Select from "@material-ui/core/Select";
import OutlinedInput from "@material-ui/core/OutlinedInput";
import MenuItem from "@material-ui/core/MenuItem";
import {makeStyles} from "@material-ui/core";
import Button from '@material-ui/core/Button';
import Typography from "@material-ui/core/Typography";
import Box from "@material-ui/core/Box";
import Link from '@material-ui/core/Link';
import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogContentText from '@material-ui/core/DialogContentText';
import DialogTitle from '@material-ui/core/DialogTitle';
import Collapse from '@material-ui/core/Collapse';
const useStyles = makeStyles(theme => ({
cellphoneCountryCodeStyle: {
marginTop: '8px',
marginBottom: '4px'
},
requestVerificationMsgBtnStyle: {
marginTop: '8px',
marginBottom: '4px',
minHeight: '40px',
},
txtLabel: {
paddingTop: '0px',
fontSize: '0.75rem',
color: 'rgba(0, 0, 0, 0.54)'
},
txtLabelGrid: {
paddingTop: '0px',
},
}));
export const CellphoneTextField = props => {
const {onStateChange} = props;
const [state, setState] = useState({
errors: [],
onChange: false,
pristine: false,
touched: false,
inProgress: false,
value: {
cellphoneCountryCode: '82',
cellphone: '',
},
verificationCode: [],
isLocked: false
});
const [open, setOpen] = useState(false);
const [verificationCode, setVerificationCode] = useState('');
const [isVerificationCodeError, setIsVerificationCodeError] = useState(false);
const handleOnClick = async (event) => {
const eventCurrentTarget = event.currentTarget.name;
if (eventCurrentTarget === 'resendBtn' || eventCurrentTarget
=== 'resetBtn') {
event.preventDefault();
}
if ((eventCurrentTarget === 'requestVerificationMsgBtn' && state.isLocked
=== false) || eventCurrentTarget === 'resendBtn') {
const updateState = {
...state,
isLocked: true,
inProgress: true,
};
setState(updateState);
onStateChange(updateState);
const lang = navigator.language;
const cellphoneCountryCode = state.value.cellphoneCountryCode;
const cellphone = state.value.cellphone;
const response = await requestMobileVerificationCode(lang,
cellphoneCountryCode, cellphone).catch(e => {});
const updatedState = {
...state,
isLocked: true,
inProgress: false,
verificationCode: state.verificationCode.concat(response),
};
setState(updatedState);
onStateChange(updatedState);
}
};
const classes = useStyles();
return (
<Grid container spacing={1}>
<Grid item xs={12} p={0} className={classes.txtLabelGrid}>
<Typography className={classes.txtLabel} component="h5" id="infoMsg"
name="infoMsg"
variant="caption">
Did not receive the code? <Link
component="button"
variant="body2"
id="resendBtn"
name="resendBtn"
to="/"
className={classes.txtLabel}
onClick={handleOnClick}
>
[resend VericationCode]
</Link>
</Typography>
<Box m={1}/>
</Grid>
</Grid>
)
};
export default CellphoneTextField;
我的单元测试代码
jest.mock("../../../../api/auth/authApiConsumer");
configure({adapter: new Adapter()});
describe('<CellphoneTextField />', () => {
const handleStateChange = jest.fn();
let shallow;
beforeAll(() => {
shallow = createShallow();
});
let wrapper;
beforeEach(() => {
wrapper = shallow(<CellphoneTextField onStateChange={handleStateChange}/>);
});
it('should allow user to resend verification code', (done) => {
act(() => {
wrapper.find('#resendBtn').simulate('click', {
currentTarget: {
name: 'resendBtn'
}
});
});
当我运行单元测试时,代码超出
event.preventDefault();
不执行。
解决方案
第二个参数.simulate('click', ...)
是一个模拟事件。
当您模拟单击时,您需要使用该事件传递一个无操作preventDefault
函数,因为您的代码正在尝试调用e.preventDefault()
但preventDefault
在(模拟)事件中不存在。
这应该有效:
wrapper.find('#resendBtn').simulate('click', {
preventDefault() {},
currentTarget: {
name: 'resendBtn'
}
});
推荐阅读
- python - 在数据框中查找特定单词
- symfony - 使用 symfony 身份验证器和 lexik jwt 身份验证
- android - 如何在没有 gradle 的情况下使用 androidx 库
- tensorflow2.0 - 在 BERT 模型上调试 TensorFlow 服务
- micronaut - 如何从 micronaut 框架中排除 slf4j?我正在使用 log4j2
- javascript - React Redux with hooks - 身份验证和受保护的路由
- python - 我似乎无法使用 openpyxl
- javascript - D3.js 可以使用“空白”分隔值获取数据吗?
- angular - 将 ContentChildren 作为模板传入
- javascript - 如何在内容丰富的 CMS 中添加代码片段