首页 > 解决方案 > 如何使用 React 测试库和 Jest 测试所需的输入字段?

问题描述

我尝试使用 React 测试库和 Jest 通过测试弹出框的存在来测试所需的输入字段,但我失败了。我尝试了几种变体,但没有一个有效。UI的步骤如下:

  1. 单击空字段 空选择字段
  2. 单击字段旁边的(模糊)
  3. 将鼠标悬停在字段上
  4. 获取所需消息所需消息

实现这一目标的测试代码是:

  const input = screen.getByRole('textbox', {name: /name \*/i})
  expect(input).toBeTruthy();
  fireEvent.click(input);
  fireEvent.blur(input);
  await waitFor(() => expect(input).toHaveValue(config.EMPTY_STRING));

  act(() => {
    fireEvent.mouseOver(input);
  });

  await waitFor(() => {
    expect(screen.getByText('Name is required')).toBeTruthy();
  });

不幸的是,它不起作用,我收到此错误: TestingLibraryElementError: Unable to find an element with the text: Name is required。这可能是因为文本被多个元素分解。在这种情况下,您可以为您的文本匹配器提供一个功能,以使您的匹配器更加灵活。

我以这种方式更改了最后一行: expect(screen.getByText('Name is required')).toBeInTheDocument();但得到了同样的错误。

我试过 expect(screen.findByText('Name is required')).toBeInTheDocument();但得到了同样的错误。

我的最后一次尝试是:expect(screen.findByText('Name is required')).toBeTruthy();。在这里,该领域的测试通过了,但整体测试失败了。我得到的错误是:console.error 警告:您似乎有重叠的 act() 调用,这是不受支持的。在进行新的调用之前,请务必等待先前的 act() 调用。错误:未捕获 [TypeError:无法读取属性 'useRealTimers' of null]

所以我被卡住了。任何帮助将非常感激。非常感谢!

标签: reactjsjestjsreact-testing-library

解决方案


我认为这是不可能的,因为 HTML5 验证的弹出窗口是由浏览器处理的。

Jest 是一个基于节点的运行器。create-react-app文档描述得最好:

Jest 是一个基于节点的运行器。这意味着测试总是在 Node 环境中运行,而不是在真正的浏览器中。这使我们能够实现更快的迭代速度并防止片状。

虽然 Jest 通过 jsdom 提供了诸如 window 之类的浏览器全局变量,但它们只是真实浏览器行为的近似值。Jest 旨在用于逻辑和组件的单元测试,而不是 DOM 怪癖。

如果需要,我们建议您使用单独的工具进行浏览器端到端测试。

如果您想测试弹出窗口,您可以使用正确的工具来完成这项工作,例如 Cypress。你可以参考这个

^ 这是我使用的方法。然后在测试库中我测试“我的工作”,即

实际上触发验证的浏览器实现并不是真正测试您的工作(而是测试浏览器本身),这可能很好,但在我看来是不必要的。

因此,在您的示例中,由于需要输入并且您希望出现弹出窗口,因此可以假设输入的值仍然为空。所以我们为此写了一个断言:

expect(input).toHaveValue("")
// I also add some css to highlight the required input,
// so I assert on that
expect(input).toHaveClass("is-required")

推荐阅读