e.preventDefault阻止我使用酶进行单元测试

时间:2019-07-28 23:43:13

标签: reactjs enzyme jest

我有一个带有按钮的reactJS应用程序。

当用户按下按钮时,用户会在手机上获得验证码。

起初,当用户按下按钮时,表格会随机刷新,但我发现我必须使用

event.preventDefault();

停止按钮刷新。

因此在我的onClick处理程序中,我具有以下结构。

CODE- 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">
                      &nbsp;&nbsp;&nbsp;Did not receive the code? &nbsp;&nbsp;<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();

未执行。

1 个答案:

答案 0 :(得分:1)

.simulate('click', ...)的第二个参数是模拟事件。

模拟点击时,您需要通过该事件传递无操作preventDefault函数,因为您的代码正在尝试调用e.preventDefault(),但是preventDefault不存在(模拟)事件。

这应该有效:

wrapper.find('#resendBtn').simulate('click', {
  preventDefault() {},
  currentTarget: {
    name: 'resendBtn'
  }
});