我正在测试我的函数对另一个函数的调用,特别是一个作为对象的参数。
问题是sinon.js似乎存储了对其arguments数组中给出的object参数的引用,这自然是预期的。但是,当参数稍后被ref修改时会产生问题,这会在调用函数时更改这些参数的表观值。
对这种情况进行单元测试的最佳方法是什么?
这是一个人为的例子:
var view = Backbone.View.extend({
initialize: function () {
_.bindAll(this);
},
dostuff: function () {
var coords = { x: 0, y: 0 };
for (var i = 0; i < 10; i++) {
this.otherstuff(coords);
coords.x += 10;
}
},
otherstuff: function (coord) {
// Stubbed
}
});
test("a test", function() {
// Arrange
var blah = new view();
sinon.stub(blah, 'otherstuff');
// Act
blah.dostuff();
// Assert
var expectedFirstCallCoords = { x: 0, y: 0 };
// All assertions on the value of x for a particular call would seem to be impossible.
// blah.otherstuff.firstCall.args[0].x --> 100
deepEqual(blah.otherstuff.firstCall.args[0], expectedFirstCallCoords, 'parameter changed by ref, untestable?');
});
我可以想到围绕这个'问题'的各种黑客行为。有没有更简洁的方法,只是为了让sinon工作,不涉及克隆对象或修改我的生产代码?
答案 0 :(得分:7)
在related Github discussion关于Mantoni的信息:
var param = { property: 'value' };
var engage = sinon.stub();
var engageWithValue = engage.withArgs(sinon.match({ property : 'value' }));
engage(param);
param.property = 'new value';
sinon.assert.calledOnce(engageWithValue); // passes