У меня есть компонент с кнопкой, которая запускает функцию и выполняет вызов API.
// MainPage.tsx
exṕort const MainPage: FC () = () => {
const [hasApiError, setHasApiError] = useState<boolean>(false)
if (hasApiError){
<ErrorPage/>
}
return <PageWithForm submitHandler=submitHandler(setHasApiError)>
}
// PageWithForm/PageWithFormServices.tsx
export const submitHandler =
(
setHasApiError: Dispatch<SetStateAction<boolean>>
): SubmitHandler<FormData> => async (data: FormData) => {
try {
const response = await callApiAndSendForm(data)
// calls another function ...
}catch(error){
setHasApiError(true)
}
}
// services/callApiAndSendForm.ts
export const callApiAndSendForm = async (data: FormData): Promise<ResponsesFromApi> =>
fetch('/api/...', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
}).then((res) => res.json())
Я хотел бы иметь возможность проверить, правильно ли отображается компонент ErrorPage, если вызов API, submitHandler или что-либо еще делает hasApiError = true. Я не хочу напрямую издеваться над setHasApiError внутри компонента.
Я попытался пошутить над callApiAndSendForm, выполнив:
const callApiAndSendFormMock = callApiAndSendForm as jest.Mock
// ... function to renderMainPage
it('should render ErrorPage if api call fails', async () => {
callApiAndSendFormMock.mockRejectedValue('error')
const { getById } = renderMainPage()
expect(getById('error-page').toBeVisible())
})
но он возвращается TypeError: callApiAndSendForm.mockRejectedValue is not a function
Кто-нибудь может мне помочь?
Итак, хорошо! Как я могу проверить это без использования jest.Mock? Я также пытался mock.spy, и он вернул ту же ошибку.
Сначала вы должны издеваться над callApiAndSendForm
, где-то после импорта в тестовом файле:
//...
import { callApiAndSendForm } from 'services/callApiAndSendForm'
//...
jest.mock('services/callApiAndSendForm')
//...
it('should render ErrorPage if api call fails', async () => {
const callApiAndSendFormMock = callApiAndSendForm as jest.Mock
callApiAndSendFormMock.mockRejectedValue('error')
const { getById } = renderMainPage()
expect(getById('error-page').toBeVisible())
})
//...
Тогда это должно работать
Также вы можете предоставить реализацию прямо в mock-функции:
jest.mock('services/callApiAndSendForm', () => ({
callApiAndSendForm: () => Promise.reject('error'),
})
Omg, да, я должен был импортировать, прежде чем делать как шутка. Большое спасибо!
На самом деле, извините. Каким-то образом он отображает <PageWithForm submitHandler=submitHandler(setHasApiError)>, а не <ErrorPage/>. getById (или любой другой getBy...) возвращает ошибку при попытке получить. У вас есть какие-либо предложения?
Это очень легко исправить, это зависит от вашей библиотеки тестирования реакции, если вы используете test-utils, см. здесь . Просто заверните рендер в асинхронную act
функцию. Если вы используете библиотеку тестирования реакции, просто оберните свои ожидания в waitFor
см. документы
Итак, это не сработало, потому что я предполагаю, что нам нужно отобразить компонент, смоделировать отправку формы, чтобы изменить состояние setHasApiError как false, иначе это не сработает. Попытка имитировать API будет бесполезной, потому что событие кнопки еще не было запущено.
Я пытаюсь это сделать, но понятия не имею, как это сделать :'( Я очень новичок в тестах
Не беспокойтесь, вы справитесь с этим очень скоро! Во-первых, какую библиотеку тестирования вы используете? (какая библиотека предоставляет функцию getById
?) Во-вторых, перейдите к документации этой библиотеки и прочитайте, как запускать событие или имитировать щелчок. Если вы все еще застряли, я буду рад помочь вам.
TypeScript вообще не влияет на время выполнения. Использование
as
просто лжет машинописному тексту, что тип отличается