简体   繁体   English

反应。 Fromik。 Material-ui表单提交事件测试使用react-testing-library失败

[英]React. Fromik. Material-ui form submit event testing fails using react-testing-library

I have a react app using Formik and Material-ui. 我有一个使用Formik和Material-ui的React应用。 I grabbed the submit button html element, But fireEvent is not working. 我抓住了提交按钮html元素,但是fireEvent无法正常工作。 I think the issue is coming from Formik library layer. 我认为问题出在Formik库层。 'Button' component is a reusable material ui button. “按钮”组件是可重复使用的材质ui按钮。 'change fireEvent' tests are passed. 通过了“ change fireEvent”测试。

But I receive 'Expected mock function to have been called one time, but it was called zero times.' 但是我收到“预期的模拟函数被调用过一次,但被调用了零次。” message for 'submit fireEvent'. 消息“提交fireEvent”。

loginForm.test.js loginForm.test.js

import { Router, MemoryRouter } from 'react-router-dom';
import { queryByAttribute } from 'react-testing-library';
import React, { render, cleanup, fireEvent } from '../../../setupTests';
import LoginForm from '../../../../components/auth/login/loginForm';

afterEach(cleanup);

const mockSubmit = jest.fn();
const mockKeepMeLoggedIn = jest.fn();

const defaultProps = {
  handleSubmit: mockSubmit,
  isSubmitting: false,
  userData: [],
  keepMeLoggedIn: mockKeepMeLoggedIn,
};

const setUp = (props = {}) => {
  const setupProps = { ...defaultProps, ...props };
  const component = render(
    <MemoryRouter>
      <LoginForm {...setupProps} />
    </MemoryRouter>,
  );
  const { container, getByTestId, getByText } = component;
  const getByName = queryByAttribute.bind(null, 'name');
  const usernameInput = getByName(container, 'username');
  const passwordInput = getByName(container, 'password');
  const getByType = queryByAttribute.bind(null, 'type');
  const submitButton = getByType(container, 'submit');


  return { component, usernameInput, passwordInput, submitButton };
};

describe('Login Form Component', () => {
  it('simulate input type and click the form submit button', () => {
    const { usernameInput, passwordInput, submitButton } = setUp();
    fireEvent.change(usernameInput, { target: { value: 'yuch' } });
    expect(usernameInput.value).toBe('yuch');
    fireEvent.change(passwordInput, { target: { value: 'testpwd1234' } });
    expect(passwordInput.value).toBe('testpwd1234');

    fireEvent.click(submitButton);
    expect(mockSubmit).toHaveBeenCalledTimes(1);
  });

loginForm.js loginForm.js

 ...

        import { Formik, Form } from 'formik';
        /* --- Components --- */
        import FormikField from '../../../shared/form/formikField';
        import PasswordField from '../../../shared/form/passwordField';
        import Button from '../../../shared/form/formButton';

        const LoginForm = ({
          keepMeLoggedIn,
          keepLoggedIn,
          userData,
          handleSubmit,
          loginValidation,
        }) => {
          const foundUsername = userData.length !== 0 ? userData[0].username : '';
          const values = { username: foundUsername, password: '' };
          return (
            <Formik
              initialValues={values}
              validationSchema={loginValidation}
              onSubmit={handleSubmit}
            >
              {({ isSubmitting }) => (
                <div className="login-container">
                  <Form
                    className="flex flex-column-m center"
                    data-testid="form"
                  >

            <FormikField
              label="아이디"
              name="username"
              type="text"
              icon="filledUser"
              styleName="textField"
              required
            />
           ...
            <Button
              typeValue="submit"
              variantValue="contained"
              buttonName="로그인"
              className="login-btn"
              isSubmitting={isSubmitting}
            />
          </Form>
         ...
        </div>
      )}
    </Formik>
  );
};

button.js button.js

import React from 'react';
import Button from '@material-ui/core/Button';
import { withStyles } from '@material-ui/core/styles';

const styles = theme => ({
  ...
});

const FormButton = ({
  typeValue,
  variantValue,
  buttonName,
  width,
  isSubmitting,
  classes,
  className,
}) => {
  ...
  return (
    <Button
      type={typeValue}
      variant={variantValue}
      color="primary"
      size="small"
      style={widthStyle}
      className={`${className} ${classes.button}`}
      disabled={isSubmitting}
    >
      {buttonName}
    </Button>
  );
};

Things I have tried. 我尝试过的东西。

[ To get submit button ] [获取提交按钮]

  1.  const getByType = queryByAttribute.bind(null, 'type'); const submitButton = getByType(container, 'submit'); -> console.log(submitButton) // HTMLButtonElement -> fireEvent.click(submitButton) 
  2. 2. 2。
const submitButton = getByText('로그인');

-> console.log(submitButton) // HTMLSpanElement

-> fireEvent.click(submitButton)
  1.  const submitButton = getByTestId('form'); -> console.log(submitButton) // HTMLFormElement -> fireEvent.submit(submitButton) 

[ form ] 1. html 'form' instead of 'Form' from Formik. [form] 1. html'form'而不是Formik中的'Form'。

import { Formik, Form } from 'formik';

<Formik
      initialValues={values}
      validationSchema={loginValidation}
      onSubmit={handleSubmit}
    >
      {({ handleSubmit, isSubmitting }) => (
        <div className="login-container">
          <form
            className="flex flex-column-m center"
            onSubmit={handleSubmit}
            data-testid="form"
          >
          ...
          </form>

It actually has to do with how Formik handles the submit. 实际上,它与Formik处理提交的方式有关。 Since it is using a promise, it takes at least a tick before the onSubmit call is being called. 由于它使用了Promise,因此在调用onSubmit调用之前至少要花费一个勾号。

Testing library has a wait utility which waits for a given time. 测试库具有一个wait实用程序,它会等待给定的时间。 But since we only need to wait for a single tick, we can just omit the duration. 但是由于我们只需要等待一个滴答声,我们就可以省略持续时间。

First, import wait from react-testing-library. 首先,从react-testing-library导入等待。 Then make your it function async and wrap the expect part with a wait function. 然后使您的it函数async并用wait函数包装期望部分。

I've tested this with a click event on the submit button. 我已经通过“提交”按钮上的click事件进行了测试。

// import wait
import { wait } from 'react-testing-library';

// add async
it('simulate input type and click the form submit button', async () => {
  const { usernameInput, passwordInput, submitButton } = setUp();

  fireEvent.change(usernameInput, { target: { value: 'yuch' } });
  expect(usernameInput.value).toBe('yuch');

  fireEvent.change(passwordInput, { target: { value: 'testpwd1234' } });
  expect(passwordInput.value).toBe('testpwd1234');

  fireEvent.click(submitButton);

  // wrap expect in `await wait`
  await wait(() => {
    expect(mockSubmit).toHaveBeenCalledTimes(1);
  });
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 react-testing-library 测试 material-ui 数据网格时出现问题 - Problem testing material-ui datagrid with react-testing-library 反应测试库 material-ui slider - react-testing-library material-ui slider 使用带有 material-ui 的 react-testing-library 的问题 - issue working with react-testing-library with material-ui 如何使用 react-testing-library 检查 material-ui MenuItem 是否被禁用 - How to check if a material-ui MenuItem is disabled using react-testing-library 如何使用react-testing-library测试withStyles中包含的样式化的Material-UI组件? - How to test styled Material-UI components wrapped in withStyles using react-testing-library? 如何使用 react-testing-library 测试材质 ui MenuList 组件上的按键按下事件 - How to test key down event on material ui MenuList component using react-testing-library Material-UI 表单和反应测试库所需的表单字段 - Material-UI Form and React Testing Library Required Form Fields react-testing-library + material-ui 错误:元素类型无效: - react-testing-library + material-ui error: Element type is invalid: 在 react-testing-library 中按 Enter 提交表单不起作用 - Pressing enter to submit form in react-testing-library does not work 在使用 react-testing-library 进行测试期间,单击两次 material-ui 图标不会将其颜色更改为默认值 - Clicking twice material-ui icon does not change its color to default during tests with react-testing-library
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM