使用sinon使用必需的参数声明特定的存根调用

时间:2015-04-27 15:18:40

标签: unit-testing qunit 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这样的断言?

this fiddle

中的示例设置

2 个答案:

答案 0 :(得分:6)

正当我创建样本小提琴时,我找到了解决方案......

在我的代码中,我使用的是Sinon的1.7.1版本,但是在使用Sinon的最新版本(截至今天的1.14.1)编写小提琴时,我意识到您可以将特定的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);    
});

小提琴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));
});

答案 1 :(得分:6)

您可以使用sinon.assert.callOrder(spy1, spy2, ...)spy1.calledBefore(spy2)spy2.calledAfter(spy1)

这些也可以与spy.calledWith(...)的结果一起使用,例如sinon.assert.callOrder(spy.withArgs('a'), spy.withArgs('b'))