Sinon Cheatsheet - Test Doubles
Sinon.js 单元测试必备 Mock 工具都在这里了,从 spy 监听器到 fake timer 时间控制,按类别分类整理,写代码时直接复制。
Back to LanguagesSpy 间谍 8
sinon.spy(obj, "method")监听对象方法调用
sinon.spy(fn)包装函数为 spy
spy.calledOnce是否被调用一次
spy.calledWith(arg1, arg2)是否传入指定参数
spy.returned(value)是否返回指定值
spy.callCount获取调用次数
spy.args[0]获取第一次调用的参数数组
spy.restore()恢复原方法
Stub 桩函数 9
sinon.stub(obj, "method")替换对象方法为空函数
stub.returns(value)指定返回值
stub.throws(Error)抛出异常
stub.callsFake(fn)用自定义函数替代
stub.resolves(value)返回 resolved Promise(异步)
stub.rejects(Error)返回 rejected Promise(异步)
stub.callsArg(0)调用第一个参数作为回调
stub.onCall(0).returns(value)按调用次数返回不同值
stub.restore()恢复原方法
Mock 模拟 7
sinon.mock(obj)创建 mock 对象
mock.expects("method")期望方法被调用
expects.once()期望调用一次
expects.withArgs(arg)期望传入参数
expects.never()期望不被调用
mock.verify()验证所有期望
mock.restore()恢复并清除所有期望
Fake Timer 时间控制 6
sinon.useFakeTimers()接管 setTimeout/setInterval
clock.tick(1000)快进 1000 毫秒
clock.runAll()跑完所有已排队的定时器
clock.restore()恢复真实时间
sinon.useFakeTimers({ now: 1000 })设置初始时间
sinon.useFakeTimers({ toFake: ["setTimeout", "Date"] })仅伪造指定 API
断言与验证 6
sinon.assert.called(spy)断言 spy 被调用
sinon.assert.calledOnce(spy)断言调用一次
sinon.assert.calledWith(spy, arg)断言传入参数
sinon.assert.notCalled(spy)断言未被调用
sinon.assert.callCount(spy, 3)断言调用次数
sinon.assert.calledWithExactly(spy, arg)断言严格匹配参数
Sandbox 沙箱 5
sinon.createSandbox()创建独立沙箱(推荐 beforeEach 创建)
sandbox.spy(obj, "method")在沙箱中创建 spy
sandbox.stub(obj, "method")在沙箱中创建 stub
sandbox.useFakeTimers()在沙箱中使用假定时器
sandbox.restore()一次性恢复沙箱内所有 mock
实用模式 5
sinon.replace(obj, "method", fn)替换方法(推荐,优于直接 stub)
sinon.replaceGetter(obj, "prop", fn)替换对象 getter
sinon.replaceSetter(obj, "prop", fn)替换对象 setter
sinon.fake()创建不改变行为的 fake 函数
sinon.match({ id: sinon.match.number })参数匹配器(类型/结构匹配)
💡 Tips
- Spy 监听调用但不改变行为,Stub 替换行为,Mock 结合两者并验证期望。
- 测试后必须 restore() 恢复原方法,或用 sandbox 自动管理(推荐 afterEach 调 sandbox.restore)。
- Fake Timer 用于测试定时任务,避免真实等待,记得 tick 后 restore。
- sinon.assert 抛出错误,适合在测试框架中使用;也可直接读取 spy 属性断言。
- stub.resolves/rejects 处理 Promise,比 callsFake 包装 async 函数更简洁。