如何为调用外部API的StudentService中searchName函数编写单元测试
必须模拟外部API响应,具体实现步骤如下
单元测试的核心是隔离依赖,如果调用真实API,会导致测试结果受外部服务可用性、网络状态影响,完全不符合单元测试的要求。以下是基于Jest(TypeScript生态最常用的测试框架)的具体实现步骤:
1. 准备测试环境
确保已安装必要依赖:
npm install jest @types/jest ts-jest typescript --save-dev
2. 编写单元测试代码
创建测试文件student.service.spec.ts,内容如下:
import axios from 'axios'; import { StudentService } from './service'; // 全局模拟axios模块 jest.mock('axios'); // 类型断言,方便后续调用mock方法 const mockedAxios = axios as jest.MockedFunction<typeof axios>; describe('StudentService', () => { let service: StudentService; // 每个测试用例执行前重置实例和模拟 beforeEach(() => { service = new StudentService(); mockedAxios.mockReset(); }); describe('searchName', () => { it('成功调用外部API时,返回正确数据', async () => { // 1. 准备测试数据 const testParam1 = 'Alice'; const testParam2 = 'Class2'; const mockXmlRequest = '<student><name>Alice</name><class>Class2</class></student>'; const mockApiResponse = { code: 200, data: [{ id: 1, name: 'Alice', age: 16 }] }; // 2. 模拟私有方法parsetoXmlRequest的返回结果 jest.spyOn(service as any, 'parsetoXmlRequest').mockReturnValue(mockXmlRequest); // 3. 模拟axios成功响应 mockedAxios.mockResolvedValue({ data: mockApiResponse }); // 4. 调用待测试方法 const result = await service.searchName(testParam1, testParam2); // 5. 断言验证 expect(result).toEqual(mockApiResponse); // 验证axios调用参数是否符合预期 expect(mockedAxios).toHaveBeenCalledWith({ url: 'some_url', // 替换为实际的API地址 method: 'post', data: mockXmlRequest, responseType: 'json' }); // 验证私有方法是否被正确调用 expect((service as any).parsetoXmlRequest).toHaveBeenCalledWith(testParam1, testParam2); }); it('调用外部API失败时,正确捕获错误', async () => { // 1. 准备测试数据 const testParam1 = 'Bob'; const testParam2 = 'Class3'; const mockError = new Error('API timeout'); // 2. 模拟私有方法 jest.spyOn(service as any, 'parsetoXmlRequest').mockReturnValue('<xml>test</xml>'); // 3. 模拟axios抛出错误 mockedAxios.mockRejectedValue(mockError); // 4. 调用待测试方法 const result = await service.searchName(testParam1, testParam2); // 5. 断言验证(原代码catch块为空,所以返回undefined) expect(result).toBeUndefined(); // 验证axios确实被调用 expect(mockedAxios).toHaveBeenCalled(); }); }); });
3. 关键步骤说明
- 模拟axios:通过
jest.mock('axios')完全替换真实的axios模块,避免发起真实网络请求。 - 模拟私有方法:利用
jest.spyOn捕获私有方法的调用,确保参数传递正确,同时隔离其内部逻辑对测试的影响。 - 覆盖两种场景:分别测试API调用成功和失败的情况,确保代码逻辑的完整性。
内容的提问来源于stack exchange,提问作者fslzdfsl
相关产品推荐
相关产品推荐

