首页 > 解决方案 > 使用 Enzyme 测试表单验证

问题描述

我正在尝试测试当用户提交带有空输入的表单时错误是否显示在屏幕上!

我做了这个测试,一切看起来都很好,但它说长度为 0,这意味着它没有出现,我的错误在哪里?

import React, { useState } from 'react';
import { login } from '../../../services/account-service';
import validate from '../../../utility/login-validate';
import { Button, Error, Form, Input, Label, NavLink, Sign, SignBtn } from './signin-style';

/**
 * Component to log in the website if you have valid information, and display errors if the information is invalid.
 */
function Signin() {
  const [email, setemail] = useState('');
  const [errors, setErrors] = useState(null);
  const [password, setPassword] = useState('');

  /**
   *this methode called when the user presses the submit button, first it will check if there is errors, if not it will submit the form!
   *
   * @param {React.SyntheticEvent} event click on submit button event!
   */
  const handleSubmit = async (event) => {
    event.preventDefault();

    /**
     * Function that check if the user inserted wrong information and put it on `error` variable!, then it will update the 'errors' state!
     */
    const error = validate(email, password);
    setErrors(error);

    await login(email, password);
  };

  /**
   * Method that handle the change on { email input } by taking the input value and setting it on 'email' state!
   *
   * @param {React.SyntheticEvent} event when user type in email input!
   */
  const handleemailChange = (event) => {
    const user = event.currentTarget.value;
    setemail(user);
  };

  /**
   *  Method that handle the change on { password input } by taking the input value and setting it on 'password' state!
   *
   * @param {React.SyntheticEvent} event  When user type in password input
   */
  const handlePasswordChange = (event) => {
    const pass = event.currentTarget.value;
    setPassword(pass);
  };

  return (
    <Sign>
      <h1>Sign In</h1>
      <NavLink to="/login">Need an account?</NavLink>
      {errors ? <Error id="error">* Invalid email or password!</Error> : null}
      <Form>
        <div>
          <Label htmlFor="email">
            <Input
              id="email"
              onChange={handleemailChange}
              placeholder="Email"
              type="text"
              value={email}
            />
          </Label>
        </div>
        <div>
          <Label htmlFor="password">
            <Input
              id="password"
              onChange={handlePasswordChange}
              placeholder="Password"
              type="password"
              value={password}
            />
          </Label>
        </div>
        <SignBtn>
          <Button type="submit" onClick={handleSubmit}>
            Sign in
          </Button>
        </SignBtn>
      </Form>
    </Sign>
  );
}

export default Signin;

我的测试:

import { shallow } from 'enzyme';
import React from 'react';
import '../../../setup-tests';
import Signin from './Signin';

describe('Signin component', () => {
  let wrapper;
  beforeEach(() => {
    wrapper = shallow(<Signin />);
  });

  it('should display error on the screen on click', () => {
    const emailInput = wrapper.find('#email');
    const passwordInput = wrapper.find('#password');

    passwordInput.simulate('change', { currentTarget: { value: '' } });
    emailInput.simulate('change', { currentTarget: { value: '' } });

    const submitButton = wrapper.find('[type="submit"]');
    submitButton.simulate('click');

    expect(wrapper.find('#error')).toHaveLength(1);
  });
});

当我运行它时测试返回:

预期长度:1,接收长度:0,接收对象:{}

标签: reactjsunit-testingenzyme

解决方案


我认为这是因为你有一个 html 表单,而不仅仅是一个任意的提交函数。尝试识别表格,例如。<Form id='form'>并像这样测试它:

const form = wrapper.find('#form').at(0);
form.simulate('submit');

编辑 您也可以尝试:

        wrapper.update();

        setTimeout(function () {
            expect(...).toBe(...);
            done();
        }, 500);

并且不要忘记done作为测试用例函数的参数传递。


推荐阅读