I'm checking the test coverage and I'm not currently passing the fetch line (line 3). How can I test the fetch function?
Service:
export const taskManagerRemoteService = {
getTasks: (): Promise<any> => {
return fetch(`${process.env.REACT_APP_BACKEND_URL}${process.env.REACT_APP_TASKS_URI}`, {
method: "GET",
headers:{
'Content-Type': 'application/json'
}
})
}
}
Test:
import "@testing-library/react"
import { taskManagerRemoteService } from "./task-manager.remote.service";
describe("TaskManagerRemoteService", () => {
afterAll(() => {
jest.clearAllMocks()
})
it('should get tasks when getTasks method is called', async () => {
const spy = jest.spyOn(taskManagerRemoteService, 'getTasks').mockImplementation(() => Promise.resolve([{}]))
const tasks = await taskManagerRemoteService.getTasks();
expect(spy).toHaveBeenCalled()
expect(tasks).toStrictEqual([{}])
spy.mockReset();
spy.mockRestore();
})
})
Thank you very much in advance
CodePudding user response:
You are testing the taskManagerRemoteService.getTasks
method, so you should not mock it. You should mock the fetch
function and its resolved/rejected value.
There are two ways to mock an API request:
msw - Mock by intercepting requests on the network level. This way you have to install additional packages and set them up. It does not need to mock and uses the original
fetch
method, which is closer to the real runtime environment.global.fetch = jest.fn()
- Just mock thefetch
function, don't need to install any package. But the potentially at risk is incorrect mocks change thefetch
's behavior, the test passes, actual code fails.
Below is code using the second way:
task-manager.remote.service.ts
:
export const taskManagerRemoteService = {
getTasks: (): Promise<any> => {
return fetch(`${process.env.REACT_APP_BACKEND_URL}${process.env.REACT_APP_TASKS_URI}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
});
},
};
task-manager.remote.service.test.ts
:
import '@testing-library/react';
import { taskManagerRemoteService } from './task-manager.remote.service';
describe('TaskManagerRemoteService', () => {
let oFetch: typeof global.fetch;
beforeAll(() => {
oFetch = global.fetch;
});
afterAll(() => {
global.fetch = oFetch;
});
it('should get tasks when getTasks method is called', async () => {
global.fetch = jest.fn().mockResolvedValue([{}]);
const tasks = await taskManagerRemoteService.getTasks();
expect(global.fetch).toHaveBeenCalled();
expect(tasks).toStrictEqual([{}]);
});
});
Test result:
PASS stackoverflow/71400354/task-manager.remote.service.test.ts
TaskManagerRemoteService
✓ should get tasks when getTasks method is called (5 ms)
--------------------------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
--------------------------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
task-manager.remote.service.ts | 100 | 100 | 100 | 100 |
--------------------------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.83 s, estimated 2 s