NodeJS:如何测试内部调用API函数的函数(Mock实现)
如何Mock异步API请求编写单元测试
针对你提供的场景——firstFunction调用异步函数getData(内部用got.post发起真实API请求),我们可以通过Mock工具(以Jest为例)避免真实请求,完成单元测试。
先修正原代码的小问题
原firstFunction中调用异步函数getData时未加await,导致oo是未决的Promise对象,建议将firstFunction改为异步函数,方便后续测试:
const got = require('got'); const url = 'https://example.com/api'; const getData = async (data) => { const res = await got.post(url, { json: { data } }); return res.data; } // 修改为async函数,处理异步调用 async function firstFunction(args) { let output = args; let oo = await getData(args); console.log(oo); return oo; // 返回结果便于测试断言 } module.exports = { getData, firstFunction };
方案1:Mock got 模块的post方法
直接Mock发起请求的got.post,模拟其返回值,验证请求参数和返回结果是否符合预期。
测试文件示例(utils.test.js):
const { firstFunction, getData } = require('./utils'); const got = require('got'); // 全局Mock got模块 jest.mock('got'); describe('异步函数单元测试', () => { // 每次测试前清除Mock调用记录 beforeEach(() => jest.clearAllMocks()); test('getData 应正确调用got.post并返回Mock数据', async () => { // 定义Mock的API响应 const mockResponse = { data: { id: 1, content: '模拟返回数据' } }; // 让got.post返回一个resolved状态的Promise got.post.mockResolvedValue(mockResponse); const result = await getData('测试输入'); // 断言返回结果是否正确 expect(result).toEqual(mockResponse.data); // 断言got.post的调用次数和参数是否符合预期 expect(got.post).toHaveBeenCalledTimes(1); expect(got.post).toHaveBeenCalledWith('https://example.com/api', { json: { data: '测试输入' } }); }); test('firstFunction 应正确调用getData并处理结果', async () => { const mockResponse = { data: '处理后的模拟数据' }; got.post.mockResolvedValue(mockResponse); const result = await firstFunction('测试参数'); expect(result).toEqual(mockResponse.data); // 验证getData间接调用的got.post参数正确 expect(got.post).toHaveBeenCalledWith('https://example.com/api', { json: { data: '测试参数' } }); }); });
方案2:直接Mock getData 函数
如果只关注firstFunction的逻辑,无需验证getData内部的请求细节,可以直接MockgetData函数本身。
测试文件示例:
const { firstFunction } = require('./utils'); const { getData } = require('./utils'); // Mock getData函数,保留模块其他原函数 jest.mock('./utils', () => { const originalModule = jest.requireActual('./utils'); return { ...originalModule, getData: jest.fn() }; }); describe('firstFunction 单元测试', () => { beforeEach(() => jest.clearAllMocks()); test('firstFunction 应正确调用getData并传递参数', async () => { const mockReturnValue = '模拟返回值'; // 设置getData的Mock返回值 getData.mockResolvedValue(mockReturnValue); const result = await firstFunction('测试参数'); // 断言getData的调用次数和参数 expect(getData).toHaveBeenCalledTimes(1); expect(getData).toHaveBeenCalledWith('测试参数'); // 断言firstFunction的返回结果 expect(result).toEqual(mockReturnValue); }); });
内容的提问来源于stack exchange,提问作者orange_ball_ss
相关产品推荐
相关产品推荐

