Home > Software engineering >  How do I mock a function that calls an API
How do I mock a function that calls an API

Time:11-20

I have a component with a button that triggers a function and does a API call.

// 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())

I would like to be able to test if ErrorPage component is rendering correctly if the API call, submitHandler or anything is making hasApiError = true. I don't want to mock the setHasApiError inside of the component directly.

I tried to jest.mock the callApiAndSendForm by doing:

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())

})

but it returns TypeError: callApiAndSendForm.mockRejectedValue is not a function

Can anyone help me, please?

CodePudding user response:

You should mock callApiAndSendForm first, somewhere after imports in your test file:

//...
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())
})
//...

Then it should work

Also you can provide implementation right in mock function:

jest.mock('services/callApiAndSendForm', () => ({
  callApiAndSendForm: () => Promise.reject('error'),
})
  • Related