I'm using react-query
with react-testing-library
and msw
(mock-service-worker). Is this a correct way mock both a GET request called from a useQuery
hook when the component renders, and PUT request when the form is submitted, in one test block? Right now it looks like my PUT request isn't succeeding - it should close the modal in the onSuccess
callback in the useMutation
hook.
The test
it('submit the modal form', async () => {
// GET the projects data for the <Projects/> component
server.use(
rest.get('*', (req, res, ctx) => res(
ctx.status(200),
ctx.json(mockedResponseData)
)),
rest.put('*', (req, res, ctx) => res(
ctx.status(200),
ctx.json({
title: 'My updated title'
})
))
);
const {
queryByTestId,
getByText,
getByLabelText
} = renderWithProviders(<Projects />);
expect(await queryByTestId('my-modal')).not.toBeInTheDocument();
fireEvent.click(getByText('Open Modal'));
// change title and submit
const input = getByLabelText(/title/i);
fireEvent.change(input, { target: { value: 'My updated title' } });
// PUT request
await fireEvent.click(getByText("Save"));
// modal should unmount but this fails
expect(await queryByTestId('my-modal')).not.toBeInTheDocument();
});
More details
I think my mock for this PUT request isn't working correctly, because submitting the form in the app unmounts the modal in the onSuccess
callback of my react-query useMutation
hook, but the assertion testing if the modal was unmounted after a successful PUT request keeps failing (the modal is still in the DOM).
Things I've verified
- If I fire an event in the test to close the modal, the modal is unmounted and the assertion passes, so I know that the component will unmount when closed
- The test I have for the
useMutation
hook works correctly (below)
it('returns success after updating title', async () => {
const { result, waitFor } = renderHook(() => useEditTitle(), {
wrapper: createWrapper(),
});
result.current.mutate({
id: 1,
title: 'My updated title'
});
await waitFor(() => result.current.isSuccess);
expect(result.current.isSuccess).toBe(true);
expect(result.current.data.title).toBe('My updated title');
});