(Next.Js, react-query, Vitest)
I have a modal where the user has a few steps to complete. At the last step, code sends a request to the backend. This request is sent using useMutation().mutateAsync
and in useMutation().onSuccess
I handle showing the success screen.
I aim to mock my useUpload
hook to test with what parameters it has been called.
const mockedUpload = vi.fn();
vi.mock('hooks/useUpload.tsx', () => ({
useUpload: () => ({
mutateAsync: mockedUpload,
}),
}));
// ...
expect(mockedMutate).toHaveBeenCalledWith({ test: '123' })
It works, but unfortunately, it breaks showing the success screen since it is set from onSuccess
which in this mocked version is never called. Ideally mocked mutateAsync
should call actual onSuccess
but I didn’t manage the mocking code.
Any ideas?
The useUpload
hook looks like this:
export const useUpload = ({ onSuccess }: UseUploadProps = {}) => {
const mutation = useMutation({
mutationFn: async (props: UploadProps) => uploadFile(props),
onSuccess() {
onSuccess?.();
},
});
return { ...mutation, isLoading: mutation.isPending };
};
2
Answers
I found the other way, which takes passed
onSuccess
and calls it directly frommutateAsync
instead of mocking wholeuseMutation
so that it'smutateAsync
should call actualonSuccess
which should call passedonSuccess
. Finally mock looks like this:and to separate it as a variable:
and usage like:
Are there any better ways of fixing the mentioned issue? If so, I would love to hear and learn.
Another way is also to use
msw
and check request body directly in theserver.use()
like following: