I'm trying [redux toolkit][1] for the first time and haven't found helpful docs on how to test the ui response to api calls.
I have seen [jest-fetch-mock][2] suggested for mocking the calls which are a bit hidden in syntactic sugar.
currently my code works, but I can't find a good way to mock the 500 I should get from my api call to test a particular scenario. Here is the method that calls the api call in my RequestList.tsx file:
const updateAndRedirect = () => {
return updateCuration({ state, employeeId })
.unwrap()
.then((data) => proceedToLookPage(data.curation.ocpId))
.catch((e) => {
const errorMessage = e.data?.error
if (errorMessage === "Cannot read property 'state' of null") {
setHasNoRequestsInQueue(true)
} else {
setHasError(true)
}
})
}
<Container>
<Box>
{error && hasNoRequestsInQueue && (
message="No new requests to start"
})
</Box>
</Container>
test file (react testing library preferred):
import { fireEvent, getByText, render, waitFor } from '@testing-library/react'
import { Provider } from 'react-redux'
import { store } from 'app/store'
import RequestList from 'scenes/RequestList'
import fetchMock, { enableFetchMocks } from 'jest-fetch-mock'
import userEvent from '@testing-library/user-event'
beforeEach((): void => {
// enableFetchMocks()
fetchMock.resetMocks()
})
describe('RequestList', () => {
it('should render a "no requests in queue" message if the call fails', async () => {
const { getByText } = render(
<Provider store={store}>
<RequestList />
</Provider>
)
fetchMock.mockReject(new Error("Cannot read property 'state' of null"))
await waitFor(() => fireEvent.click(getByText(/start new/)))
await waitFor(
() => expect(getByText('No new requests to start')).toBeInTheDocument
)
When I run this test it fails because the error being thrown looks like:
{
status: 'FETCH_ERROR',
error: "Error: Cannot read property 'state' of null"
}
I want the error to look like:
{
status: 500,
data: {
error: "Cannot read property 'state' of null"
}
}
So that my code declaring the const errorMessage can be run. It is looking for e.data?.error but I can't nest the mocked error message in that shape.
Since it works locally I believe it is my mock that needs to change.
Any ideas how to mock the response better? Or a different strategy for testing rtk post requests altogether?
[1]: https://redux-toolkit.js.org/introduction/getting-started
[2]: https://github.com/wheresrhys/fetch-mock-jest
Finally solved this! The docs for jest-fetch-mock are not very user friendly imo.
Even though I am trying to mock an error I needed to use the mockResponse() function.
fetchMock.mockResponse( JSON.stringify({ error: "Cannot read property 'state' of null" }), { status: 500 } )
where { error: "Cannot read property 'state' of null" }
is the body of the error message returned in the network tab.
For some reason the mockReject() function makes assumptions about what the error body should look like, and it was very different from what my error looked like.