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

如何用Mocha、Sinon和Chai测试回调内的两次HTTP调用?

如何测试回调内部嵌套的HTTP调用

嘿,我明白你的困扰了!你现在的问题核心是Sinon对http.get的stub默认不会自动执行回调函数,导致你代码里嵌套的那层http.get('/')根本没机会被调用,所以测试里只能检测到一次调用。别担心,调整一下测试代码就能解决这个问题,我来一步步给你讲清楚:

问题根源

你在测试里stub了http.get,但默认情况下这个stub只会“假装”调用了方法,不会执行它的回调参数。而你代码里的第二次http.get是在第一次http.get的回调里,所以如果不手动让stub执行这个回调,那层嵌套的请求永远不会触发。

解决方法:让Sinon Stub执行回调

Sinon提供了callsArg方法,可以让stub在被调用时执行指定位置的回调参数。对于http.get来说,它的第二个参数就是回调函数,所以我们需要让stub调用这个回调。

修改后的测试代码

const Index = require('../index')
const http = require('http')
const { stub, assert } = require('sinon')
const { expect } = require('chai')

let a;
let httpSpy;

beforeEach(function () {
  a = new Index()
  // 这里修改stub,让它调用第二个参数(回调函数)
  httpSpy = stub(http, 'get').callsArg(1)
})

afterEach(function () {
  // 别忘了恢复stub,避免影响其他测试
  http.get.restore()
})

describe('When the get method is invoked', function () {
  beforeEach(function () {
    a.get('http://www.google.co.uk')
  })

  it('should make two calls to the http service', function () {
    // 验证http.get被调用了两次
    assert.calledTwice(httpSpy)
    // 验证第一次调用的参数是传入的uri
    assert.calledWith(httpSpy.firstCall, 'http://www.google.co.uk')
    // 验证第二次调用的参数是'/'
    assert.calledWith(httpSpy.secondCall, '/')
  })
})

关键修改点解释

  1. stub(http, 'get').callsArg(1):这句告诉Sinon,当http.get被调用时,执行它的第2个参数(索引从0开始,所以1对应第二个参数)也就是回调函数,这样嵌套在回调里的http.get('/')才会被执行。
  2. 添加afterEach恢复stub:每次测试后恢复http.get的原始方法,防止不同测试之间互相影响。
  3. 验证两次调用的参数:用firstCall和secondCall分别获取两次调用的实例,验证它们的参数是否符合预期。

这样调整后,你的测试就能正确检测到两次http.get的调用了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:54:15