简体   繁体   English

使用带有 material-ui 的 react-testing-library 的问题

[英]issue working with react-testing-library with material-ui

Trying to write my first test with react-testing-library, but it seems like it would not grab the correct material-ui element.尝试用 react-testing-library 编写我的第一个测试,但它似乎无法获取正确的 material-ui 元素。

https://codesandbox.io/s/lx5nl1839z https://codesandbox.io/s/lx5nl1839z

I get the error message saying the event was never fired.我收到一条错误消息,指出该事件从未被触发。

Expected mock function to have been called one time, but it was called zero times.预期模拟函数被调用一次,但它被调用了零次。

When I change the button to a regular button instead of Button from material ui, then it works.当我将button更改为常规按钮而不是材料 ui 中的按钮时,它就可以工作了。

Here is my test这是我的测试

test('calls with user email and password', () => {
  const login = jest.fn();
  const error = null as any;

  const { getByLabelText, getByText } = render(
    <LoginForm login={login} error={error} />
  );

  const email = getByLabelText('Email');
  const password = getByLabelText('Password');
  (email as any).value = 'leoq91@gmail.com';
  (password as any).value = 'password';
  fireEvent.click(getByText('Login'));


  expect(login).toHaveBeenCalledTimes(1);
  expect(login).toHaveBeenCalledWith({
      email: 'leoq91@gmail.com',
      password: 'password',
  });
});

Here is my component:这是我的组件:

export const LoginForm: FunctionComponent<IProps> = ({ login, error }) => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  return (
    <Paper style={{ width: '400px', padding: '30px', margin: '0 auto' }}>
      <form
        onSubmit={e => {
          e.preventDefault();
          return login({ email, password });
        }}
      >
        <TextField
          id="email"
          label="Email"
          onChange={e => setEmail(e.target.value)}
          fullWidth
          variant="outlined"
          error={Boolean(getEmailError(email))}
          helperText={getEmailError(email)}
        />
        <TextField
          id="password"
          label="Password"
          type="password"
          style={{ marginTop: '10px' }}
          onChange={e => setPassword(e.target.value)}
          fullWidth
          variant="outlined"
        />
        <LoginError error={error} />
        <Button
          variant="contained"
          color="primary"
          type="submit"
          fullWidth
          // disabled={isDisabled(email, password)}
          style={{
            margin: '20px 0px',
          }}
        >
          Login
        </Button>
      </form>
      <Divider />
      <Typography style={{ margin: '10px auto' }}>Forgot password?</Typography>
    </Paper>
  );
};

First, codesandbox is not reliable...首先,codesandbox 不可靠......

codesandbox is somehow running the tests in the browser and not in jsdom. codesandbox 以某种方式在浏览器中而不是在 jsdom 中运行测试。

Here is the issue: https://github.com/kentcdodds/react-testing-library/issues/234这是问题所在: https ://github.com/kentcdodds/react-testing-library/issues/234

Gist of it is because it is clicking the submit span, not the button.它的要点是因为它单击的是submit范围,而不是按钮。 It should have bubbled up, but it isn't.它应该冒泡了,但它没有。

Here is a working example with my local server with Typescript.这是一个使用 Typescript 的本地服务器的工作示例。

test('calls with user email and password', () => {
    const login = jest.fn();

    const { getByLabelText, container } = render(
      <LoginForm login={login} error={null} />
    );

    const emailNode = getByLabelText('Email');
    const passwordNode = getByLabelText('Password');

    if (
      emailNode instanceof HTMLInputElement &&
      passwordNode instanceof HTMLInputElement
    ) {
      fireEvent.change(emailNode, { target: { value: 'leoq91@gmail.com' } });
      fireEvent.change(passwordNode, { target: { value: 'password' } });
      const form = container.querySelector('form') as HTMLFormElement;
      form.dispatchEvent(new Event('submit'));
      expect(login).toHaveBeenCalledTimes(1);
      expect(login).toHaveBeenCalledWith({
        email: emailNode.value,
        password: passwordNode.value,
      });
    } else {
      expect(false);
    }
  });

Your TextFields are not controlled.您的 TextFields 不受控制。 You should pass the actual value and set the actual value in the change event.您应该传递实际值并在更改事件中设置实际值。 You fire submit twice currently in your tests.您当前在测试中触发了两次提交。

Running the tests with those fixes has the correct console output but for some reason codesandbox ignores the jest matcher.使用这些修复程序运行测试具有正确的控制台输出,但出于某种原因,codesandbox 忽略了笑话匹配器。 I don't know what's going on there but with the above fixes the gist of it works.我不知道那里发生了什么,但通过上述修复,它的要点起作用了。

I have been figthing over this for a while and finally got something to put the data-testid on the input and not the div around it that composed the TextField in material-ui.我已经为此纠结了一段时间,终于找到了一些东西来将 data-testid 放在输入上,而不是在它周围构成 material-ui 中的 TextField 的 div。

You should set the data-testid in the inputProps like this:您应该像这样在 inputProps 中设置data-testid

<TextField
     type="password"
     variant="outlined"
     required
     value={password}
     onChange={onChangePassword}
     inputProps={{
         'data-testid': 'testPassword'
     }}
 />

And then you can access it in your test like that and simulate a new user input:然后你可以像那样在你的测试中访问它并模拟一个新的用户输入:

const passwordInput = getByTestId('testPassword');
fireEvent.change(passwordInput, { target: { value: VALID_PASSWORD } });

I saw many people having issues with material-ui.我看到很多人对 material-ui 有疑问。 My guess is that Button is trying to do some fancy thing and breaks the normal HTML event flow.我的猜测是Button试图做一些花哨的事情并打破正常的 HTML 事件流。

My advice is to use jest.mock() and mock Button to render a button instead.我的建议是使用jest.mock()和 mock Button来渲染一个button

声明:本站的技术帖子网页,遵循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 如何使用react-testing-library测试withStyles中包含的样式化的Material-UI组件? - How to test styled Material-UI components wrapped in withStyles using react-testing-library? react-testing-library + material-ui 错误:元素类型无效: - react-testing-library + material-ui error: Element type is invalid: 如何使用 react-testing-library 检查 material-ui MenuItem 是否被禁用 - How to check if a material-ui MenuItem is disabled using react-testing-library 反应。 Fromik。 Material-ui表单提交事件测试使用react-testing-library失败 - React. Fromik. Material-ui form submit event testing fails using react-testing-library 在使用 react-testing-library 进行测试期间,单击两次 material-ui 图标不会将其颜色更改为默认值 - Clicking twice material-ui icon does not change its color to default during tests with react-testing-library 使用 material-ui 库反应渲染问题 - React rendering issue with material-ui library Material-UI 表单和反应测试库所需的表单字段 - Material-UI Form and React Testing Library Required Form Fields React-Testing 库未在快照中呈现 Material-UI 对话框 - React-Testing library not rendering Material-UI Dialog in snapshot
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM