I am currently mocking an internal dependency in a react project this way:
import { QueryClient, QueryClientProvider } from "react-query";
import { render } from "@testing-library/react";
import SectionCourses from "./SectionCourses";
const queryClient = new QueryClient({});
jest.mock("@myORG/axiosWrapperReactQuery", () => {
const original = jest.requireActual("@myORG/axiosWrapperReactQuery");
return {
...original,
getAllCourses: jest.fn().mockImplementation(() => ({
isLoading: false,
typedData: [],
})),
};
});
it("not found", async () => {
const { findByText } = render(
<QueryClientProvider client={queryClient}>
<SectionCourses />
</QueryClientProvider>
);
const firstCourse = await findByText("No courses found");
expect(firstCourse).toBeInTheDocument();
});
It works perfectly but when I try to mock the dependency again in the same file it fails
// ALL THE PREVIOUS CODE
jest.mock("@myORG/axiosWrapperReactQuery", () => {
const original = jest.requireActual("@myORG/axiosWrapperReactQuery");
return {
...original,
getAllCourses: jest.fn().mockImplementation(() => ({
isLoading: true, // This was changed to true
typedData: [],
})),
};
});
it("is loading", async () => {
const { findByText } = render(
<QueryClientProvider client={queryClient}>
<SectionCourses />
</QueryClientProvider>
);
const firstCourse = await findByText("Loading...");
expect(firstCourse).toBeInTheDocument();
});
It seems that only takes the last jest.mock
So what will be the way to handle this if I need to mock that funcion many times so I can see what my React Component will display?
I know I can create multiple files like SectionCourses-V1.test.tsx
, SectionCourses-V2.test.tsx
... but having so many files it's not ideal
Note: This is not a duplicate of Jest -- Mock a function called inside a React Component
CodePudding user response:
You can move the implementation of mock inside the test method itself so that each test method works on the provided mock implementation.
it("not found", async () => {
jest.mock("@myORG/axiosWrapperReactQuery", () => {
const original = jest.requireActual("@myORG/axiosWrapperReactQuery");
return {
...original,
getAllCourses: jest.fn().mockImplementation(() => ({
isLoading: true, // This was changed to true
typedData: [],
})),
};
});
const { findByText } = render(
<QueryClientProvider client={queryClient}>
<SectionCourses />
</QueryClientProvider>
);
const firstCourse = await findByText("No courses found");
expect(firstCourse).toBeInTheDocument();
});
it("is loading", async () => {
jest.mock("@myORG/axiosWrapperReactQuery", () => {
const original = jest.requireActual("@myORG/axiosWrapperReactQuery");
return {
...original,
getAllCourses: jest.fn().mockImplementation(() => ({
isLoading: true, // This changed to true
typedData: [],
})),
};
});
const { findByText } = render(
<QueryClientProvider client={queryClient}>
<SectionCourses />
</QueryClientProvider>
);
const firstCourse = await findByText("Loading...");
expect(firstCourse).toBeInTheDocument();
});
CodePudding user response:
You can chain the mock implementations of getAllCourses jest docs
Try this,
jest.mock("@myORG/axiosWrapperReactQuery", () => {
const original = jest.requireActual("@myORG/axiosWrapperReactQuery");
return {
...original,
getAllCourses: jest.fn()
.mockImplementationOnce(() => ({
isLoading: false, // 1st call
typedData: [],
}))
.mockImplementationOnce(() => ({
isLoading: true, // 2nd call
typedData: [],
}))
}