如何测试从后端获取的 React 服务
How can I test a React Service that fetchs from a backend
我正在检查测试覆盖率,但我目前没有通过 fetch 行(第 3 行)。如何测试获取功能?
服务:
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'
}
})
}
}
测试:
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();
})
})
非常感谢您
你正在测试 taskManagerRemoteService.getTasks
方法,所以你不应该模拟它。您应该模拟 fetch
函数及其 resolved/rejected 值。
有两种方法可以模拟 API 请求:
msw - 通过拦截网络级别的请求进行模拟。这样你就必须安装额外的包并进行设置。不需要mock,使用原始的fetch
方式,更接近真实的运行环境
global.fetch = jest.fn()
- 只需模拟 fetch
函数,不需要安装任何包。但潜在的风险是不正确的模拟改变了 fetch
的行为,测试通过,实际代码失败。
下面是使用第二种方式的代码:
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([{}]);
});
});
测试结果:
PASS Whosebug/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
我正在检查测试覆盖率,但我目前没有通过 fetch 行(第 3 行)。如何测试获取功能?
服务:
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'
}
})
}
}
测试:
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();
})
})
非常感谢您
你正在测试 taskManagerRemoteService.getTasks
方法,所以你不应该模拟它。您应该模拟 fetch
函数及其 resolved/rejected 值。
有两种方法可以模拟 API 请求:
msw - 通过拦截网络级别的请求进行模拟。这样你就必须安装额外的包并进行设置。不需要mock,使用原始的
fetch
方式,更接近真实的运行环境global.fetch = jest.fn()
- 只需模拟fetch
函数,不需要安装任何包。但潜在的风险是不正确的模拟改变了fetch
的行为,测试通过,实际代码失败。
下面是使用第二种方式的代码:
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([{}]);
});
});
测试结果:
PASS Whosebug/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