Я пытаюсь протестировать 2 useState
хуков, которые запускаются во время цепочки обещаний после отправки формы.
Все хуки, прикрепленные к элементу (например, электронная почта, кнопка отправки) работают нормально , но это те, которые обновляют состояние в цепочке обещаний, к которым я не знаю, как получить доступ для имитации / тестирования.
// 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
Документация не кажется особенно полезной, поскольку в ней используется простой пример, а не тестирование побочных эффектов.
ПРИМЕЧАНИЕ: я бы предпочел избегать использования ферментов, если это возможно.
Спасибо заранее