如何使用Sinon对包含axios.post调用的异步方法进行Mock?
问题排查及修复方案
核心错误原因
- 未等待异步函数执行完成:
controller.result是异步方法,测试代码中直接调用未加await,断言执行时axios.post逻辑还未运行,自然检测不到调用 - 未Mock外部依赖:没有对
axios.post和Producer.produce做stub处理,一是Producer.produce会调用真实的Azure Event Hub接口,大概率会阻塞或报错导致后续axios.post无法执行,二是Sinon无法监听未被stub的方法调用 - 测试入参不全:构造的
req对象缺少query.param属性,导致link生成结果为/search,和你断言预期的/login不匹配,就算axios.post被调用也会断言失败 - 多处语法错误导致代码逻辑无法正常执行
需先修复的基础语法错误
- Controller.js 修复:
- 函数参数不能直接写字面量
"login",调整为合法参数名 axios.post行尾的冒号:改为分号;- 提前定义变量
team的取值 - 所有
require路径补全引号,比如require('./Producer')
- 函数参数不能直接写字面量
- Producer.js 修复:
catch块中throw e改为throw error,e未定义
- controller-test.js 修复:
- 回调函数语法修正:
describe("execute", =>{改为describe("execute", () => {,it回调同理 - 断言行的字符串引号补全,参数匹配
axios.post的入参规则
- 回调函数语法修正:
修正后的测试代码示例
const sinon = require('sinon'); const axios = require('axios'); const producer = require('./Producer'); const controller = require('./controller'); describe("execute", () => { // 每个用例执行前stub外部依赖 beforeEach(() => { // 模拟axios.post返回成功 sinon.stub(axios, 'post').resolves({}); // 模拟produce方法,避免调用真实Event Hub接口 sinon.stub(producer, 'produce').resolves(); }); // 每个用例执行后恢复stub,避免污染其他用例 afterEach(() => { sinon.restore(); }); it("call method to post", async () => { // 构造完整req对象,假设team常量取值为'team',保证link生成'/login' const req= { query: { param: 'team' }, name:"tina", dob:"2-12-2000" }; // 等待异步方法执行完成 await controller.result(req, {}, "login"); // 断言axios.post被调用且参数正确 sinon.assert.calledOnce(axios.post); sinon.assert.calledWith(axios.post, '/login', req.name, req.dob); }); });
内容的提问来源于stack exchange,提问作者vishnu
相关产品推荐
相关产品推荐

