reactjs - React 测试库 - 隔离测试和 userEvent 错误

标签 reactjs react-testing-library

我正在使用 Jest 和 React 测试库编写测试。我的测试失败了,我意识到如果我改变测试的顺序,它就会起作用。我猜这是因为测试没有正确隔离,一个测试可能会影响另一个测试。

我正在打电话:

afterEach(() => {
  cleanup()
  jest.resetAllMocks()
})

我有一个如下所示的测试:

it('calls API when submitted', async () => {
   render(<SignUp />)
   fillAllVerificationFieldsWithTestData()
   validateUser.mockResolvedValueOnce({ id: 123 })      
   const signupButton = screen.getByTestId(
      'sign-up-verification-button',
    )  
    userEvent.click(signupButton)     
    await waitFor(() => expect(validateUser).toHaveBeenCalledTimes(1))      
 })

如果我使用 userEvent.click 创建完全相同的测试或运行类似的测试,则会收到错误:

无法触发“mouseMove”事件 - 请提供 DOM 元素。

我查看了 @testing-library/user-event 库,看到了以下代码:

const userEvent = {
  click(element) {
    const focusedElement = element.ownerDocument.activeElement;
    const wasAnotherElementFocused =
      focusedElement !== element.ownerDocument.body &&
      focusedElement !== element;
    if (wasAnotherElementFocused) {
      fireEvent.mouseMove(focusedElement);
      fireEvent.mouseLeave(focusedElement);
    }

我注意到 element.ownerDocument.activeElement 为 null wasAnotherElementFocused 为 true,因此它抛出错误。

我第一次运行测试时它不为空,所以它可以工作。

我需要在测试之间进行一些额外的清理吗?如果我使用 fireEvent:

 fireEvent(signupButton,
      new MouseEvent('click', {
          bubbles: true,
      }),
   )

它有效,但我担心我做错了什么并且没有正确隔离我的测试。

编辑:

以下是 fillAllVerificationFieldsWithTestData 的代码:

export const fillAllVerificationFieldsWithTestData = () => {
  const { given_name, family_name, zip, social, loanNumber } = {
    given_name: screen.getByTestId('given_name'),
    family_name: screen.getByTestId('family_name'),
    zip: screen.getByTestId('zip'),
    social: screen.getByTestId('last4ssn'),
    loanNumber: screen.getByTestId('loan_number'),
  }

  userEvent.type(given_name, 'FirstName')
  userEvent.type(family_name, 'LastName')
  userEvent.type(zip, '77025')
  userEvent.type(social, '1234')
  userEvent.type(loanNumber, '1112223333')
}

screen 是从 @testing-library/react 导入的,我像这样导入验证用户:

import { validateUser } from '../../../services/auth'
jest.mock('../../../services/auth')

最佳答案

所以,我刚刚遇到了这个问题,解决这个问题的方法是将导致 React 状态更改的任何代码(您的 userEvent 代码可能会这样做)包装在 act 中>。因此,您的初始测试将如下所示:

it('calls API when submitted', async () => {
   render(<SignUp />)
   fillAllVerificationFieldsWithTestData()
   validateUser.mockResolvedValueOnce({ id: 123 })      
   const signupButton = screen.getByTestId(
      'sign-up-verification-button',
    )  
    await act(() => userEvent.click(signupButton))     
    await waitFor(() => expect(validateUser).toHaveBeenCalledTimes(1))      
 })

您能否尝试一下,对 fillAllVerificationFieldsWithTestData 函数应用类似的更改,并让我们知道结果如何?

关于reactjs - React 测试库 - 隔离测试和 userEvent 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61490164/

相关文章:

reactjs - react typescript 如何键入一个 hoc

javascript - 在测试中完成提取时异步路径更新

react-testing-library - React 快照测试 - react-test-renderer 与 react-testing-library

reactjs - MouseEnter/MouseOver 不适用于 react-testing-library。如何使用 react-testing-library 测试悬停事件

reactjs - Jest-dom 给出错误 "TypeError: expect(...).toHaveStyle is not a function"

javascript - 在一个事件中 react 触发多个功能

javascript - 将项目推送到嵌套对象数组

javascript - 如何加载外部js文件并在reactjs中使用它们的数据?

css - 如何在聊天室中将聊天条目右对齐?

javascript - 单元测试失败,错误为 "Cypress command timeout of ' 超过 4000 毫秒。”