使用 sinon 使用所需的参数断言特定的存根调用
Asserting a specific stub call was made with the required arguments using sinon
假设您正在测试一个将使用不同参数多次调用依赖项的函数:
var sut = {
ImportantFunction: function(dependency){
dependency("a", 1);
dependency("b", 2);
}
};
使用 QUnit + Sinon 并假设调用顺序不重要,我可以编写以下测试以确保函数按预期调用依赖项:
test("dependency was called as expected", function () {
var dependencyStub = sinon.stub();
sut.ImportantFunction(dependencyStub);
ok(dependencyStub.calledTwice, "dependency was called twice");
sinon.assert.calledWith(dependencyStub, "a", 1);
sinon.assert.calledWith(dependencyStub, "b", 2);
});
但是如果顺序很重要并且我希望测试考虑到它怎么办?使用 QUnit+Sinon 编写此类测试的最佳方法是什么?
我使用了以下方法,但我丢失了 sinon assertions 提供的描述性失败消息(显示预期值和实际值)。为此,我只是手动添加了一些描述性消息,但它不如包含预期值和实际值的失败消息有用(并且必须手动维护)。
ok(dependencyStub.firstCall.calledWith("a", 1), "dependency called with expected args 'a', 1");
ok(dependencyStub.secondCall.calledWith("b", 2), "dependency called with expected args 'b', 2");
有没有一种方法可以针对特定调用(如第一次或第二次调用)使用 sinon.assert.calledWith
之类的断言?
中的示例设置
就在我创建示例时 fiddle 我找到了解决方案...
在我的代码中,我使用的是 Sinon 的 1.7.1 版,但是在使用 Sinon 的最新版本(截至今天为 1.14.1)编写 fiddle 时,我刚刚意识到您可以将特定的 spyCall 传递给assert.calledWith
方法。这意味着您可以编写以下内容:
sinon.assert.calledWith(dependencyStub.firstCall, "a", 1);
sinon.assert.calledWith(dependencyStub.secondCall, "b", 2);
所以我想创建的测试可以写得很好:
test("dependency was called multiple times as expected - with order", function () {
var dependencyStub = sinon.stub();
sut.ImportantFunction(dependencyStub);
sinon.assert.calledTwice(dependencyStub);
sinon.assert.calledWith(dependencyStub.firstCall, "a", 1);
sinon.assert.calledWith(dependencyStub.secondCall, "b", 2);
});
Fiddle here
编辑
在引入此更改的 github 存储库 the discussion 中找到。 到更改合并到 master 的日期,这应该适用于 1.13.0 和更新版本。
如果您使用的是旧版本,您可以使用 mantoni 的解决方案:
test("dependency was called multiple times as expected with order - pre 1.13.0", function () {
var dependencyStub = sinon.stub();
sut.ImportantFunction(dependencyStub);
sinon.assert.calledTwice(dependencyStub);
sinon.assert.callOrder(
dependencyStub.withArgs("a", 1),
dependencyStub.withArgs("b", 2));
});
您可以使用 sinon.assert.callOrder(spy1, spy2, ...)
,或 spy1.calledBefore(spy2)
或 spy2.calledAfter(spy1)
。
这些也可以与 spy.calledWith(...)
的结果一起使用,例如sinon.assert.callOrder(spy.withArgs('a'), spy.withArgs('b'))
.
假设您正在测试一个将使用不同参数多次调用依赖项的函数:
var sut = {
ImportantFunction: function(dependency){
dependency("a", 1);
dependency("b", 2);
}
};
使用 QUnit + Sinon 并假设调用顺序不重要,我可以编写以下测试以确保函数按预期调用依赖项:
test("dependency was called as expected", function () {
var dependencyStub = sinon.stub();
sut.ImportantFunction(dependencyStub);
ok(dependencyStub.calledTwice, "dependency was called twice");
sinon.assert.calledWith(dependencyStub, "a", 1);
sinon.assert.calledWith(dependencyStub, "b", 2);
});
但是如果顺序很重要并且我希望测试考虑到它怎么办?使用 QUnit+Sinon 编写此类测试的最佳方法是什么?
我使用了以下方法,但我丢失了 sinon assertions 提供的描述性失败消息(显示预期值和实际值)。为此,我只是手动添加了一些描述性消息,但它不如包含预期值和实际值的失败消息有用(并且必须手动维护)。
ok(dependencyStub.firstCall.calledWith("a", 1), "dependency called with expected args 'a', 1");
ok(dependencyStub.secondCall.calledWith("b", 2), "dependency called with expected args 'b', 2");
有没有一种方法可以针对特定调用(如第一次或第二次调用)使用 sinon.assert.calledWith
之类的断言?
就在我创建示例时 fiddle 我找到了解决方案...
在我的代码中,我使用的是 Sinon 的 1.7.1 版,但是在使用 Sinon 的最新版本(截至今天为 1.14.1)编写 fiddle 时,我刚刚意识到您可以将特定的 spyCall 传递给assert.calledWith
方法。这意味着您可以编写以下内容:
sinon.assert.calledWith(dependencyStub.firstCall, "a", 1);
sinon.assert.calledWith(dependencyStub.secondCall, "b", 2);
所以我想创建的测试可以写得很好:
test("dependency was called multiple times as expected - with order", function () {
var dependencyStub = sinon.stub();
sut.ImportantFunction(dependencyStub);
sinon.assert.calledTwice(dependencyStub);
sinon.assert.calledWith(dependencyStub.firstCall, "a", 1);
sinon.assert.calledWith(dependencyStub.secondCall, "b", 2);
});
Fiddle here
编辑
在引入此更改的 github 存储库 the discussion 中找到。 到更改合并到 master 的日期,这应该适用于 1.13.0 和更新版本。
如果您使用的是旧版本,您可以使用 mantoni 的解决方案:
test("dependency was called multiple times as expected with order - pre 1.13.0", function () {
var dependencyStub = sinon.stub();
sut.ImportantFunction(dependencyStub);
sinon.assert.calledTwice(dependencyStub);
sinon.assert.callOrder(
dependencyStub.withArgs("a", 1),
dependencyStub.withArgs("b", 2));
});
您可以使用 sinon.assert.callOrder(spy1, spy2, ...)
,或 spy1.calledBefore(spy2)
或 spy2.calledAfter(spy1)
。
这些也可以与 spy.calledWith(...)
的结果一起使用,例如sinon.assert.callOrder(spy.withArgs('a'), spy.withArgs('b'))
.