I'm using a custom react hook to perform two GET operations using react query. The API is in a separate module and uses both getTestByUid() and getTestStatuses() inside useQuery.
// TestHook.js
import { useQuery } from "react-query"
export const useTest = (uid) => {
const { data: test } = useQuery("test", () => getTestByUid(uid));
const { data: testStatuses } = useQuery("statuses", () => getTestStatusesByUid(uid));
return {
test,
testStatuses
}
}
My tests are defined as follows:
// test-hook.test.js
import { renderHook } from "@testing-library/react-hooks";
import { QueryClient, QueryClientProvider } from "react-query";
import { useTest } from "../src/hooks/TestHook";
import * as testApi from "../src/api/test-api.js";
const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: false,
},
},
});
const wrapper = ({ children }) => {
return (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
);
};
describe("useTestHook", () => {
it("should return a test", async () => {
jest
.spyOn(testApi, "getTestByUid")
.mockImplementationOnce(() =>
Promise.resolve({ data: { name: "secret test" } })
);
const { result, waitForNextUpdate } = renderHook(
() => useTest("bb450409-d778-4d57-a4b8-70fcfe2087bd"),
{ wrapper: wrapper }
);
await waitForNextUpdate();
expect(result.current.test).toBe({ name: "secret test" });
});
it("should return statuses for a test", async () => {
jest.spyOn(testApi, "getTestStatusesByUid").mockImplementationOnce(() =>
Promise.resolve({
data: ["in_progress", "ready_for_approval", "rejected"],
})
);
const { result, waitForNextUpdate } = renderHook(
() => useTest("bb450409-d778-4d57-a4b8-70fcfe2087bd"),
{ wrapper: wrapper }
);
await waitForNextUpdate();
expect(result.current.testStatuses).toBe([
"in_progress",
"ready_for_approval",
"rejected",
]);
});
});
The first test passes fine but in the second test I get undefined returned when trying to assert testStatuses value. Why might this be happening when I am spying on the getTestStatusesByUid api call?
You should mock
getTestStatusesByUidandgetTestByUidfor each test case, otherwise, the test case is not isolated.These two test cases test the return value of the
useTesthook, so there is no need to separate them. One test case is enough.Besides, the mock resolved values for both APIs are not correct based on the expected value in assertion statement. Since
useQueryreturns adatafield to hold the resolved value, wrap the resolved value into{ data: "mock resolved value" }is not necessary.E.g.
api.js:test-hook.js:test-hook.test.js:Test result:
package versions: