reactjs - 使用react-testing-library在表单中提交时如何测试已调用的函数?

标签 reactjs jestjs react-testing-library

在我的 React Signup 组件中有一个表单,用户可以在其中输入他们的电子邮件、密码和密码确认。我正在尝试使用 jest/react-testing-library 编写测试,但是由于接收到的函数调用次数为 0,预期调用次数为 1,因此测试一直失败。

我尝试过 Jest 匹配器的变体,例如 .toHaveBeenCalled()、.toHaveBeenCalledWith(arg1, arg2, ...)、toBeCalled(),所有这些都仍然期望值为 1 或更大但失败,因为接收到的数字为 0。我已经尝试了 fireEvent.click 和 fireEvent.submit ,这两个都失败了。

注册.js

export const Signup = ({ history }) => {
  const classes = useStyles();

  const [signup, setSignup] = useState({
    email: null,
    password: null,
    passwordConfirmation: null,
  });
  const [signupError, setSignupError] = useState('');

  const handleInputChange = e => {
    const { name, value } = e.target;

    setSignup({ ...signup, [name]: value });
    console.log(signup);
  };

  const submitSignup = e => {
    e.preventDefault();
    console.log(
      `Email: ${signup.email}, Pass: ${signup.password}, Conf: ${signup.passwordConfirmation}, Err: ${signupError}`
    );
};

return (
    <main>
        <form onSubmit={e => submitSignup(e)} className={classes.form}>
         <TextField onChange={handleInputChange}/>
         <TextField onChange={handleInputChange}/>
         <TextField onChange={handleInputChange}/>
         <Button
            type="submit">
           Submit
         </Button>

注册.test.js
import React from 'react';
import { BrowserRouter } from 'react-router-dom';
import { render, cleanup, fireEvent } from '@testing-library/react';

import { Signup } from '../Components/Signup';

afterEach(cleanup);

const exampleSignup = {
  email: 'test123@test123.com',
  password: 'test123',
  passwordConfirm: 'test123',
};

describe('<Signup />', () => {
  test('account creation form', () => {

    const onSubmit = jest.fn();

    const { getByLabelText, getByText } = render(
      <BrowserRouter>
        <Signup onSubmit={onSubmit} />
      </BrowserRouter>
    );

    const emailInput = getByLabelText(/Enter your Email */i);
    fireEvent.change(emailInput, { target: { value: exampleSignup.email } });
    const passInput = getByLabelText(/Create a Password */i);
    fireEvent.change(passInput, { target: { value: exampleSignup.password } });
    const passCInput = getByLabelText(/Confirm Password */i);
    fireEvent.change(passCInput, {
      target: { value: exampleSignup.passwordConfirm },
    });

    fireEvent.submit(getByText(/Submit/i));

    expect(onSubmit).toHaveBeenCalledTimes(1);
  });
});

试运行结果
账户创建表格
expect(jest.fn()).toHaveBeenCalledTimes(expected)

Expected number of calls: 1
Received number of calls: 0

最佳答案

在您的 SignUp.test.js 中,您将 onSubmit 函数作为 Prop 传递,但是该 Prop 从未在您的 SignUp 组件中使用。这就是为什么您的 onSubmit 函数从未被调用的原因。
现在关于您的问题的答案, react 测试库不鼓励测试实现细节(例如测试已调用的函数),因此无法使用 react 测试库对其进行测试(尽管您可以使用其他框架进行测试,例如使用 jest .spyOn 您的功能,这样就可以做到这一点)
推荐的是测试提交功能的结果。例如,假设您想在单击提交按钮后显示(感谢您注册),在这种情况下,您将使用 expect(screen.getByText("Thank you for signing up")).toBeInTheDocument() 进行测试。运行后 fireEvent.submit(getByText(/Submit/i))仅供引用:由于您使用的是 jest,因此您无需在每次测试后调用清理函数。

关于reactjs - 使用react-testing-library在表单中提交时如何测试已调用的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58739474/

相关文章:

reactjs - 开 Jest 错误,需要 Babel “^7.0.0-0” ,但加载了 “6.26.3”

javascript - 有没有人成功地使用 react-testing-library 来测试 draftJS Editor 组件上的更改事件?

reactjs - 如何使用 react-testing-library 测试包装在 withStyles 中的样式化的 Material-UI 组件?

reactjs - 使用 React Router V4 重定向到 ReactJS 组件上的服务器路由

javascript - 为什么它不能以这种方式显示用户点击显示在模态中的内容?

javascript - Reactjs - 为什么我的 MaterialUI 数据表不刷新?

javascript - 我如何定位被单击的 React 组件

reactjs - Jest 无法找到模块 FileName.css(映射为identity-obj-proxy)

rxjs - 无法从 'rxjs/testing' 找到模块 'jasmine-marbles.umd.js'

react-testing-library - 类型错误 : Expected container to be an Element, 文档或文档片段但得到字符串