Sinon.JS 断言库 for Chai
Sinon–Chai 提供了一组自定义断言,用于将 Sinon.JS 间谍、存根和模拟框架与 Chai 断言库一起使用。您将获得 Chai 的所有优点以及 Sinon.JS 的所有强大工具。
无需使用 Sinon.JS 的断言
sinon.assert.calledWith(mySpy, "foo");
或笨拙地尝试在间谍属性上使用 Chai 的 should 或 expect 接口
mySpy.calledWith("foo").should.be.ok;
expect(mySpy.calledWith("foo")).to.be.ok;
您可以说
mySpy.should.have.been.calledWith("foo");
expect(mySpy).to.have.been.calledWith("foo");
断言
您最喜欢的所有 Sinon.JS 断言都进入了 Sinon–Chai。我们在此展示了 should 语法; expect 等效项也可用。
| Sinon.JS 属性/方法 | Sinon–Chai 断言 | 
|---|---|
| 已调用 | spy.should.have.been.called | 
| callCount | spy.should.have.callCount(n) | 
| 已调用一次 | spy.should.have.been.calledOnce | 
| 已调用两次 | spy.should.have.been.calledTwice | 
| 已调用三次 | spy.should.have.been.calledThrice | 
| 在之前调用 | spy1.should.have.been.calledBefore(spy2) | 
| 在之后调用 | spy1.should.have.been.calledAfter(spy2) | 
| 在之前立即调用 | spy.should.have.been.calledImmediatelyBefore(spy2) | 
| 在之后立即调用 | spy.should.have.been.calledImmediatelyAfter(spy2) | 
| 使用 new 调用 | spy.should.have.been.calledWithNew | 
| 始终使用 new 调用 | spy.should.always.have.been.calledWithNew | 
| 在...上调用 | spy.should.have.been.calledOn(context) | 
| 始终在...上调用 | spy.should.always.have.been.calledOn(context) | 
| 使用...调用 | spy.should.have.been.calledWith(…args) | 
| 始终使用...调用 | spy.should.always.have.been.calledWith(…args) | 
| 使用...调用一次 | spy.should.always.have.been.calledOnceWith(…args) | 
| 使用完全相同的...调用 | spy.should.have.been.calledWithExactly(…args) | 
| 始终使用完全相同的...调用 | spy.should.always.have.been.calledWithExactly(…args) | 
| 使用完全相同的...调用一次 | spy.should.always.have.been.calledOnceWithExactly(…args) | 
| 使用匹配的...调用 | spy.should.have.been.calledWithMatch(…args) | 
| 始终使用匹配的...调用 | spy.should.always.have.been.calledWithMatch(…args) | 
| 已返回 | spy.should.have.returned(returnVal) | 
| 始终已返回 | spy.should.have.always.returned(returnVal) | 
| 已抛出 | spy.should.have.thrown(errorObjOrErrorTypeStringOrNothing) | 
| 始终已抛出 | spy.should.have.always.thrown(errorObjOrErrorTypeStringOrNothing) | 
有关每个断言行为的更多信息,请参阅 相应间谍方法的文档。这些当然不仅适用于间谍,而且适用于单个间谍调用、存根和模拟。
请注意,您可以使用 Chai 的 .not 否定任何断言。例如,对于 notCalled,请使用 spy.should.have.not.been.called。
对于 assert 接口,不需要此库。您可以使用 expose 将 Sinon.JS 断言 直接安装到 Chai 的 assert 对象中。
var chai = require("chai");
var sinon = require("sinon");
sinon.assert.expose(chai.assert, { prefix: "" });
示例
使用 Chai 的 should
"use strict";
var chai = require("chai");
var sinon = require("sinon");
var sinonChai = require("sinon-chai");
chai.should();
chai.use(sinonChai);
function hello(name, cb) {
    cb("hello " + name);
}
describe("hello", function () {
    it("should call callback with correct greeting", function () {
        var cb = sinon.spy();
        hello("foo", cb);
        cb.should.have.been.calledWith("hello foo");
    });
});
使用 Chai 的 expect
"use strict";
var chai = require("chai");
var sinon = require("sinon");
var sinonChai = require("sinon-chai");
var expect = chai.expect;
chai.use(sinonChai);
function hello(name, cb) {
    cb("hello " + name);
}
describe("hello", function () {
    it("should call callback with correct greeting", function () {
        var cb = sinon.spy();
        hello("foo", cb);
        expect(cb).to.have.been.calledWith("hello foo");
    });
});
安装和使用
节点
执行 npm install --save-dev sinon-chai 来启动和运行。然后
var chai = require("chai");
var sinonChai = require("sinon-chai");
chai.use(sinonChai);
您当然可以将此代码放在一个通用的测试夹具文件中;有关使用 Mocha 的示例,请参阅 Sinon–Chai 测试本身。
AMD
Sinon–Chai 支持用作 AMD 模块,匿名注册自身(就像 Chai 一样)。因此,假设您已将加载器配置为将 Chai 和 Sinon–Chai 文件映射到相应的模块 ID "chai" 和 "sinon-chai",您可以按如下方式使用它们
define(function (require, exports, module) {
    var chai = require("chai");
    var sinonChai = require("sinon-chai");
    chai.use(sinonChai);
});
<script> 标签
如果您在 Chai 本身的 <script> 标签之后直接包含 Sinon–Chai,那么它将自动插入 Chai 并准备使用。请注意,您还需要获取 Sinon.JS 的最新浏览器版本。
<script src="chai.js"></script>
<script src="sinon-chai.js"></script>
<script src="sinon.js"></script>
Ruby on Rails
感谢 Cymen Vig,现在有一个 Sinon–Chai 的 Ruby gem,可以将其与 Rails 资产管道集成!