我正在使用 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/