I am trying to mock 2 API requests in each test. See the code below to better understand what I mean:
// exported mock request 1
export const mockSearchList = () => {
return jest.fn(() =>
Promise.resolve({
ok: true,
status: 200,
json: () => Promise.resolve(mockedData)
})
);
};
// exported mock request 2
export const mockApiData = () => {
return jest.fn(() =>
Promise.resolve({
ok: true,
status: 200,
json: () => Promise.resolve(mockedData)
})
);
};
// RTL & React
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { prettyDOM } from '@testing-library/dom';
import { act } from 'react';
// Redux
import { BrowserRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import { store } from "../../redux/store";
// i18next
import { I18nextProvider } from 'react-i18next';
import i18next from "../../app/i18n";
// Components
import Details from '../Details';
// Mocks
import { mockSearchList } from '../../mocks/list';
import { mockApiData } from '../../mocks/apiData';
const mockDetails = () => {
return(
<Provider store={store}>
<BrowserRouter>
<I18nextProvider i18n={i18next}>
<Details />
</I18nextProvider>
</BrowserRouter>
</Provider>
)
}
describe("REST API Data", () => {
// Mock API requests (list & details data)
global.fetch = jest.fn() as jest.Mock;
beforeEach(() => {
(fetch as jest.Mock).mockImplementationOnce(mockSearchList());
(fetch as jest.Mock).mockImplementationOnce(mockApiData());
});
afterEach(() => {
jest.resetAllMocks();
});
it('should display details data from the REST API', async () => {
await act(async () => {
render(
mockDetails()
);
});
const searchInput =
await screen.findByLabelText(/Search Input/i) as HTMLInputElement;
await act(async () => {
fireEvent.input(searchInput, { target: { value: "tomato" } });
});
const searchBtn = screen.getByLabelText(/Search Button/i) as HTMLInputElement;
await act(async () => {
fireEvent.click(searchBtn);
});
const detailsHeading = await screen.findByTestId(/details-heading/i);
expect(detailsHeading).toHaveTextContent('pomidor');
});
/* Copy & paste the test here */
});
Basically, the test renders the parent component, types something inside the input (it automatically requests the mockSearchList() data and generates a list of elements from the returned data), then the test clicks the search button (searches for the first result generated from the previous data) and sends another request for the details about the item, which should populate some elements, including the details-heading with “Tomato” text.
TL;DR – Type something and a list of elements shows up, click the search button and get the detailed data.
So, the test itself works perfectly fine if I stop there.
However, if I add another test using the mocked API data, it fails (the added one fails, but the first test passes). If the test does NOT use the mocked API data, it passes as well.
What could be the cause of it? Is there a way to fix it?