【发布时间】:2020-05-09 18:42:07
【问题描述】:
我正在尝试测试在提交表单后在 Promise 链中触发的 2 个 useState 钩子。
所有附加到元素的钩子(例如电子邮件、提交按钮)都可以正常工作,但它会更新 Promise 链中的状态,我不知道如何访问以进行模拟/测试。
// submit function in ContactForm.tsx
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault()
const data = { firstName, lastName, email, message, subscribe }
setLoading(true)
fetchWrapper('/', encode(data))
.then(() => {
setStatus(true) // <= throws 'act(() => {...)' error
props.onSubmit(data) // mock function passed in to check data submitted matches
})
.catch(error => {
setStatus(false) // <= throws 'act(() => {...)' error
})
.finally(() => setLoading(false))
}
// ContactForm.spec.tsx
import React from 'react'
import { mocked } from 'ts-jest/utils'
import { render, fireEvent } from '@testing-library/react'
import ContactForm, { ContactFormProps } from './ContactForm'
import { fetchWrapper } from '../../../utils/fetchWrapper'
jest.mock('../../../utils/fetchWrapper')
let mockedFetch
beforeEach(() => {
jest.clearAllMocks()
mockedFetch = mocked(fetchWrapper)
})
it('should submit with firstName, lastName, email, message and subscribe', () => {
// ASSEMBLE
const onSubmit = jest.fn()
const utils = renderContactForm({
subscribe: false,
onSubmit,
})
const firstName = utils.getByTestId('firstName')
const lastName = utils.getByTestId('lastName')
const email = utils.getByTestId('email')
const message = utils.getByTestId('message')
const subscribe = utils.getByTestId('subscribe')
const submit = utils.getByTestId('SEND MESSAGE')
mockedFetch.mockImplementationOnce(() => Promise.resolve())
// ACT
fireEvent.change(firstName, { target: { value: 'Clark' } })
fireEvent.change(lastName, { target: { value: 'Kent' } })
fireEvent.change(email, { target: { value: 'lastson@krypton.com' } })
fireEvent.change(message, { target: { value: 'I like the sun' } })
fireEvent.click(subscribe)
fireEvent.click(submit)
// ASSERT
expect(onSubmit).toHaveBeenCalledWith({
firstName: 'Clark',
lastName: 'Kent',
email: 'lastson@krypton.com',
message: 'I like the sun',
subscribe: true,
})
})
我看到的错误是:
Warning: An update to ContactForm inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser
文档似乎不是特别有用,因为它们使用了一个简单的示例,而不是测试副作用
注意:如果可能,我宁愿避免使用酶
提前致谢
【问题讨论】:
标签: jestjs react-hooks ts-jest