【问题标题】:Stubbing a mock's method with Sinon.js使用 Sinon.js 存根模拟方法
【发布时间】:2016-03-15 16:55:29
【问题描述】:

在使用 Sinon.js 和 Buster.js 进行测试时,我无法使用 mock 替换我的类的依赖项。

我正在测试 B 类,它依赖于 A 类。我使用 Sinon.js 创建 A 类的模拟对象,并将其传递给 B 类的实例。在我的测试中,我调用 @987654321对象B的@方法,然后调用对象A的getData方法。(虽然getData方法实际上是在A的原型上,而不是A本身)。

但是当我运行测试时,我得到了错误:

TypeError: a.getData is not a function

如果我尝试存根 A 原型的 getData 方法,则会收到错误:

TypeError: Attempted to wrap getData which is already stubbed

错误发生在我设置mock_A.expects('getData') 的行上。 这是我正在运行的课程和测试:

function A(){};
A.prototype = {
    "getData" : function(oDataToGet, cb) {
        var aData = ['someData'];
        cb(aData);
    }
}
function B() {
    var a;
    this.setA = function(oA){
        a = oA;
    };
    this.doSomething = function(oObj){
        a.getData({}, function(aData){if(!aData){throw new Error('No data');} oObj.data = aData[0];});
    }
}


var oB, assert = buster.referee.assert;
buster.testCase('myTest', {
    "setUp" : function()
    {
        oB = new B();
    },
    "test_Mock" : function()
    {
        var mock_A = sinon.mock(new A());
            oB.setA(mock_A);
    //        sinon.stub(A.prototype, 'getData').callsArgWith(1, ['hi']);
        mock_A.expects('getData')
            .withArgs({})
            .once();
        var oTestObj = {};
        oB.doSomething(oTestObj)
        mock_A.verify();
    }
});

编辑 2016-03-16 添加: 一种解决方法是使用存根实例而不是模拟,然后将需要检查的方法设置为期望值:

var stubbed_A = sinon.createStubInstance(A);
stubbed_A.getData = sinon.expectation.create('getData')
    .withArgs({})
    .once();
oB.setA(stubbed_A);
var oTestObj = {};
oB.doSomething(oTestObj);
stubbed_A.getData.verify();

【问题讨论】:

    标签: javascript unit-testing sinon buster.js


    【解决方案1】:

    sinonJS 与其他模拟框架(如 Mockito、jMock 等)之间的差异会造成这种误解。在大多数模拟框架中,您创建模拟依赖项并将其注入到待测试对象 (SUT) 中,就像您所做的那样:

    var mock_A = sinon.mock(new A());
    oB.setA(mock_A);
    

    但是,在 sinonJS 中,您必须注入原始对象并使用生成的模拟对象来分配对原始对象的期望。因此,如果您使用以下内容更改前 2 行,您的测试将按预期工作:

    var a = new A();
    var mock_A = sinon.mock(a);
    oB.setA(a);
    

    当我们想要控制我们正在测试的对象的依赖项的行为时,存根更合适。当我们想要确保特定事件发生在我们正在测试的对象的依赖项上时(通过期望),模拟更合适。因此,在这种情况下,模拟对象会比存根更合适,就像您第一次尝试时一样。

    【讨论】:

      猜你喜欢
      • 2014-01-31
      • 1970-01-01
      • 2017-02-17
      • 1970-01-01
      • 2012-09-30
      • 2020-07-01
      • 2016-08-16
      • 1970-01-01
      • 2016-09-17
      相关资源
      最近更新 更多