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

如何为父函数内部调用的特定API请求函数设置stub开展测试

单独stub子函数的实现方案

前置调整:抽离可mock的请求函数

首先要把request1、request2等独立的外部请求函数抽成单独的模块导出,只有导出的函数才能被stub工具捕获替换:

// requests.js 抽离后的公共请求模块
import request from 'request-promise'
export const request1 = async (data) => request({uri: "service1.com/get", method: "GET"})
export const request2 = async (data) => request({uri: "service2.com/get", method: "GET"})
export const request3 = async (data) => request({uri: "service3.com/get", method: "GET"})
export const request4 = async (data) => request({uri: "service4.com/get", method: "GET"})

调整原有业务代码的导入逻辑:

import {request1, request2, request3, request4} from './requests.js'

export const apiRequests = async (data) => {
   const req1 = await request1(data);
   const req2 = await request2(data);

   if (req1 && req2) {
    const req3 = await request3(data);
    const req4 = await request4(data);

    return "Second return"
   }
   return "First return"
}

编写测试用例(基于Loopback testlab内置能力)

Loopback testlab内置了stub能力,无需额外引入第三方包,你可以单独为每个请求函数设置自定义返回值:

// 测试文件
import {stub, expect} from '@loopback/testlab';
import {apiRequests} from './你的业务代码文件路径.js';
import * as requestServices from './requests.js';

// 测试返回First return的分支
it('返回First return当request1返回false时', async () => {
  // 单独stub request1返回false,不影响其他函数逻辑
  const stubReq1 = stub(requestServices, 'request1').resolves(false);
  // 按需设置request2的返回值
  const stubReq2 = stub(requestServices, 'request2').resolves(true);

  const result = await apiRequests({test: '测试数据'});
  expect(result).to.equal('First return');

  // 测试结束恢复原函数,避免影响其他用例
  stubReq1.restore();
  stubReq2.restore();
})

// 测试返回Second return的分支
it('返回Second return当request1和request2都返回true时', async () => {
  const stubReq1 = stub(requestServices, 'request1').resolves(true);
  const stubReq2 = stub(requestServices, 'request2').resolves(true);
  // 也可单独stub后续的req3、req4返回值
  const stubReq3 = stub(requestServices, 'request3').resolves('mock返回值3');
  const stubReq4 = stub(requestServices, 'request4').resolves('mock返回值4');

  const result = await apiRequests({test: '测试数据'});
  expect(result).to.equal('Second return');

  // 批量恢复所有stub
  [stubReq1, stubReq2, stubReq3, stubReq4].forEach(s => s.restore());
})

核心逻辑说明

  • stub方法会临时替换模块导出的函数引用,父函数内部调用的对应子函数会自动使用你stub后的逻辑,无需修改原有业务代码
  • 每个stub可以独立设置返回值,互相不影响,你可以按照测试分支的需要,单独控制req1返回false、req2返回true等任意组合
  • 测试用例执行结束后必须调用restore()方法恢复原函数,避免对其他测试用例产生干扰

其他常用场景

如果要模拟请求抛出异常的场景,把.resolves(xxx)替换为.rejects(new Error('自定义错误信息'))即可覆盖异常处理分支。

内容的提问来源于stack exchange,提问作者RoboKy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 16:36:02