如何使用 React 测试库和 Jest 测试必填输入字段?

Obi*_*adi 5 reactjs jestjs react-testing-library

我尝试通过测试弹出窗口的存在来使用 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();
  });
Run Code Online (Sandbox Code Playgroud)

不幸的是,它不起作用,我收到此错误: TestingLibraryElementError:无法找到带有文本的元素:名称是必需的。这可能是因为文本被多个元素分解。在这种情况下,您可以为文本匹配器提供一个函数,以使您的匹配器更加灵活。

我这样改变了最后一行: 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:无法读取 null 的属性“useRealTimers”]

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

Chr*_*odd 8

jest-dom现在有一个toBeValidtoBeInvalid定义匹配器。

it("should show the validity", async () => {
  let { user } = prep(<ComponentToTest />)
  let requiredRadioOption = screen.getByLabelText("radio-option-0")

  expect(requiredRadioOption).toBeInvalid()

  await user.click(requiredRadioOption)

  expect(requiredRadioOption).toBeValid()
})

Run Code Online (Sandbox Code Playgroud)


nel*_*les 2

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

Jest 是一个基于 Node 的运行器。create-react-app文档对此进行了最好的描述:

Jest 是一个基于 Node 的运行器。这意味着测试始终在 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")
Run Code Online (Sandbox Code Playgroud)