Как смоделировать функцию, которая вызывает API

У меня есть компонент с кнопкой, которая запускает функцию и выполняет вызов 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

Кто-нибудь может мне помочь?

TypeScript вообще не влияет на время выполнения. Использование as просто лжет машинописному тексту, что тип отличается

Konrad 20.11.2022 09:22

Итак, хорошо! Как я могу проверить это без использования jest.Mock? Я также пытался mock.spy, и он вернул ту же ошибку.

Lucy 20.11.2022 09:27
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
2
110
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Сначала вы должны издеваться над 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, да, я должен был импортировать, прежде чем делать как шутка. Большое спасибо!

Lucy 20.11.2022 09:39

На самом деле, извините. Каким-то образом он отображает <PageWithForm submitHandler=submitHandler(setHasApiError)>, а не <ErrorPage/>. getById (или любой другой getBy...) возвращает ошибку при попытке получить. У вас есть какие-либо предложения?

Lucy 21.11.2022 21:25

Это очень легко исправить, это зависит от вашей библиотеки тестирования реакции, если вы используете test-utils, см. здесь . Просто заверните рендер в асинхронную act функцию. Если вы используете библиотеку тестирования реакции, просто оберните свои ожидания в waitFor см. документы

Evgeny 22.11.2022 09:14

Итак, это не сработало, потому что я предполагаю, что нам нужно отобразить компонент, смоделировать отправку формы, чтобы изменить состояние setHasApiError как false, иначе это не сработает. Попытка имитировать API будет бесполезной, потому что событие кнопки еще не было запущено.

Lucy 22.11.2022 14:08

Я пытаюсь это сделать, но понятия не имею, как это сделать :'( Я очень новичок в тестах

Lucy 22.11.2022 14:09

Не беспокойтесь, вы справитесь с этим очень скоро! Во-первых, какую библиотеку тестирования вы используете? (какая библиотека предоставляет функцию getById?) Во-вторых, перейдите к документации этой библиотеки и прочитайте, как запускать событие или имитировать щелчок. Если вы все еще застряли, я буду рад помочь вам.

Evgeny 22.11.2022 16:09

Другие вопросы по теме