Mocking useMutation returned value
We are testing our App component and we required to mock a hook:
We mocked it with vitest and we call it on tests:
However, we have a typing problem with the mock:
What's the right way to mock it?
const useTodos = () => {
const queryClient = useQueryClient();
const { data, error, isLoading } = useQuery<Array<Todo>, Error>({
queryKey: ["todos"],
queryFn: service.fetchTodos,
});
const mutation = useMutation({
mutationFn: service.updateTodo,
onSuccess: async () => {
await queryClient.invalidateQueries({ queryKey: ["todos"] });
},
});
return { data, error, isLoading, mutation };
};
const useTodos = () => {
const queryClient = useQueryClient();
const { data, error, isLoading } = useQuery<Array<Todo>, Error>({
queryKey: ["todos"],
queryFn: service.fetchTodos,
});
const mutation = useMutation({
mutationFn: service.updateTodo,
onSuccess: async () => {
await queryClient.invalidateQueries({ queryKey: ["todos"] });
},
});
return { data, error, isLoading, mutation };
};
vi.mock("@application/hooks/updateTodo");
---
it("should renders a Spinner when it is loading", () => {
vi.mocked(useTodos).mockReturnValue({
data: undefined,
error: null,
isLoading: true,
mutation: { mutate: vi.fn() },
});
render(<App />);
expect(screen.getByText("Loading...")).toBeInTheDocument();
});
vi.mock("@application/hooks/updateTodo");
---
it("should renders a Spinner when it is loading", () => {
vi.mocked(useTodos).mockReturnValue({
data: undefined,
error: null,
isLoading: true,
mutation: { mutate: vi.fn() },
});
render(<App />);
expect(screen.getByText("Loading...")).toBeInTheDocument();
});
Type '{ mutate: Mock<Procedure>; }' is not assignable to type 'UseMutationResult<void, Error, UpdateTodoProps, unknown>'.
Type '{ mutate: Mock<Procedure>; }' is not assignable to type 'Override<MutationObserverSuccessResult<void, Error, UpdateTodoProps, unknown>, { mutate: UseMutateFunction<void, Error, UpdateTodoProps, unknown>; }> & { ...; }'.
Type '{ mutate: Mock<Procedure>; }' is missing the following properties from type 'Override<MutationObserverSuccessResult<void, Error, UpdateTodoProps, unknown>, { mutate: UseMutateFunction<void, Error, UpdateTodoProps, unknown>; }>': data, error, variables, isError, and 10 more.ts(2322)
updateTodo.ts(20, 36): The expected type comes from property 'mutation' which is declared here on type '{ data: Todo[] | undefined; error: Error | null; isLoading: boolean; mutation: UseMutationResult<void, Error, UpdateTodoProps, unknown>; }'
(property) mutation: UseMutationResult<void, Error, UpdateTodoProps, unknown>
Type '{ mutate: Mock<Procedure>; }' is not assignable to type 'UseMutationResult<void, Error, UpdateTodoProps, unknown>'.
Type '{ mutate: Mock<Procedure>; }' is not assignable to type 'Override<MutationObserverSuccessResult<void, Error, UpdateTodoProps, unknown>, { mutate: UseMutateFunction<void, Error, UpdateTodoProps, unknown>; }> & { ...; }'.
Type '{ mutate: Mock<Procedure>; }' is missing the following properties from type 'Override<MutationObserverSuccessResult<void, Error, UpdateTodoProps, unknown>, { mutate: UseMutateFunction<void, Error, UpdateTodoProps, unknown>; }>': data, error, variables, isError, and 10 more.ts(2322)
updateTodo.ts(20, 36): The expected type comes from property 'mutation' which is declared here on type '{ data: Todo[] | undefined; error: Error | null; isLoading: boolean; mutation: UseMutationResult<void, Error, UpdateTodoProps, unknown>; }'
(property) mutation: UseMutationResult<void, Error, UpdateTodoProps, unknown>
1 Reply
harsh-harlequin•13mo ago
useMutation returns more than just the mutate function. Either you mock everything you return, or you don't return the full mutation.