I am practicing because I am interested in the React Testing Library with Jest.
I'm writing a unit test of the component, but I keep getting errors, so I'd like to ask you a question.
First, I am writing a component for webtoon information and there is a custom hook called useWebtoonsQuery in it.
The useWebtoonsQuery is as follows.
const useWebtoonsQuery = () => {
const webtoons = new WebtoonService();
const queryClient = useQueryClient();
const toggleFollowing = useMutation(({ id }: IToggle) => webtoons.followWebtoon(id));
const webtoonAlimToggle = (id: number) => {
const queryClient = useQueryClient();
return useMutation(() => webtoons.updateWebtoonAlim(id));
};
return {
toggleFollowing,
webtoonAlimToggle,
};
};
export default useWebtoonsQuery;
And I wrote the test code as follows to confirm that the bell-shaped button is pressed well in the unit test (if pressed well, the color of the icon will change).
function withRouter(routes: React.ReactNode, initialEntry = "/") {
return (
<MemoryRouter initialEntries={[initialEntry]}>
<Routes>{routes}</Routes>
</MemoryRouter>
);
}
function withQuery(ui: React.ReactNode) {
const testClient = createTestQueryClient();
const { rerender, ...result } = render(
<QueryClientProvider client={testClient}>{ui}</QueryClientProvider>
);
return {
...result,
rerender: (rerenderUi: React.ReactElement) =>
rerender(
<QueryClientProvider client={testClient}>
{rerenderUi}
</QueryClientProvider>
),
};
}
// WebtoonInfo.test.tsx
jest.mock("../../../hooks/useWebtoonsQuery", () => ({
__esModule: true,
default: () => ({
data: testData,
toggleFollowing: {
mutate: jest.fn(),
},
webtoonAlimToggle: jest.fn().mockReturnValue({
mutate: jest.fn(),
}),
}),
}));
describe("WebtoonInfo component", () => {
it("should call webtoonAlimToggle.mutate when bell button is clicked", () => {
withQuery(
withRouter(
<Route
path="/"
element={
<RecoilRoot>
<WebtoonInfo data={testData} />
</RecoilRoot>
}
/>
)
);
const bellButton = screen.getByLabelText("bell");
userEvent.click(bellButton);
const useWebtoonsQuery = jest.fn().mockReturnValue({
webtoonAlimToggle: jest.fn().mockReturnValue({
mutate: jest.fn(),
}),
});
const { webtoonAlimToggle } = useWebtoonsQuery();
expect(webtoonAlimToggle.mutate).toHaveBeenCalledTimes(1);
});
});
However, contrary to the expected results, the following error occurred.
expect(received).toHaveBeenCalledTimes(expected)
Matcher error: received value must be a mock or spy function
Received has value: undefined
145 | const { webtoonAlimToggle } = useWebtoonsQuery();
146 |
> 147 | expect(webtoonAlimToggle.mutate).toHaveBeenCalledTimes(1);
| ^
148 | });
149 | });
150 |
I want to mock custom hook for useQuery and proceed with UI testing only.
And we are going to test the custom hook separately.
However, I am not writing the code well because I am not knowledgeable, so I would appreciate it if you could tell me how to solve it.