You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 12:10:53