I’m looking to test the call my function makes to another function, particularly an argument that is an object.
The issue is that sinon.js seems to store a reference to the object parameter given in its arguments array, which is naturally expected. However, this creates a problem when the parameter is later modified by ref, which changes the apparent value of those parameters at the time the function was called.
What’s the best way to unit test a situation like this?
Here is a contrived example:
http://jsfiddle.net/xtfQu/
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?');
});
I can think of various hacks around this ‘issue’. Is there a cleaner approach that doesn’t involve cloning the object or modifying my production code simply for the sake of getting sinon to work?
Credit to Mantoni on the related Github discussion on this: