简体   繁体   English

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

[英]React Testing Library - testing in isolation and userEvent error

I'm writing tests using Jest and React Testing Library.我正在使用 Jest 和 React 测试库编写测试。 I had failing tests and I realized that if I change the order of the tests, it will work.我有失败的测试,我意识到如果我改变测试的顺序,它会起作用。 I'm guessing this is because the tests aren't properly isolated and one test might affect the other.我猜这是因为测试没有正确隔离,一个测试可能会影响另一个。

I am calling:我打电话给:

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

I have a test that looks like this:我有一个看起来像这样的测试:

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))      
 })

If I create the exact same test or run a similar test after this one with a userEvent.click, I get an error:如果我使用 userEvent.click 创建完全相同的测试或在此测试之后运行类似的测试,我会收到错误消息:

Unable to fire a "mouseMove" event - please provide a DOM element.无法触发“mouseMove”事件 - 请提供 DOM 元素。

I looked in the @testing-library/user-event library and I see this code:我查看了@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);
    }

I noticed that element.ownerDocument.activeElement is null wasAnotherElementFocused is true and so it throws the error.我注意到element.ownerDocument.activeElement is null wasAnotherElementFocused是真的,所以它会抛出错误。

The first time I run the test it isn't null so it works.我第一次运行测试它不是 null 所以它可以工作。

Do I need some extra clean up between tests?我需要在测试之间进行一些额外的清理吗? If I use fireEvent:如果我使用fireEvent:

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

It works but I'm afraid I'm doing something wrong and not isolating my tests correctly.它有效,但我担心我做错了什么并且没有正确隔离我的测试。

EDIT:编辑:

Here is the code for the fillAllVerificationFieldsWithTestData:这是 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')
}

and screen is imported from @testing-library/react and I import validate user like this:并且screen是从@testing-library/react导入的,我像这样导入验证用户:

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

This is a bug that was reported in the testing-library/user-event GitHub and it should be fixed as of v11.0.1 .这是在 testing-library/user-event GitHub 中报告的错误, 应该从 v11.0.1 开始修复 It's specific to userEvent , which is why fireEvent works.它特定于userEvent ,这就是fireEvent起作用的原因。

Note that you shouldn't need to call cleanup if you're using Jest because it will get called for you .请注意,如果您使用 Jest,则不需要调用cleanup ,因为它会为您调用

So, I just faced this problem, and what fixed it for me was wrapping any code that causes a React state change (which your userEvent code presumably does) in act .所以,我刚刚遇到了这个问题,为我解决的问题是将导致 React state 更改(您的userEvent代码可能会这样做)的任何代码包装在act中。 So, your initial test would look like this:因此,您的初始测试将如下所示:

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))      
 })

Can you give this a try, applying similar changes to your fillAllVerificationFieldsWithTestData function, and let us know how it turned out?您可以尝试一下,对您的fillAllVerificationFieldsWithTestData function 应用类似的更改,然后告诉我们结果如何?

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

相关问题 反应测试 | 从“@testing-library/user-event”导入 userEvent 会生成错误“toBeInTheDocument 不是函数” - React Testing | importing userEvent from '@testing-library/user-event' generates error "toBeInTheDocument is not a function" 反应测试库 - userEvent 上传到输入:“找不到 toLowerCase” - React testing library - userEvent upload to input: "cannot find toLowerCase" 带有 userEvent.click 错误 act() 警告的反应测试库 - React Testing Library with userEvent.click wrong act() warning 使用 userEvent、fireEvent 和常规点击之间的反应测试库点击之间的差异 - React testing library differences between clicks using userEvent, fireEvent and regular clicks React 测试库:何时使用 userEvent.click 以及何时使用 fireEvent - React Testing Library: When to use userEvent.click and when to use fireEvent 反应测试:userEvent.click 不起作用 - react-testing: userEvent.click does not work React-testing-libary userEvent Hover 不起作用? - React-testing-libary userEvent Hover does'nt work? 使用 React 测试库测试 Stripe - Testing Stripe with React Testing Library 使用反应测试库测试我的组件时出现此错误 - Getting this error while testing my component using react testing library react-testing-library validateDOMNesting错误 - react-testing-library validateDOMNesting Error
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM