1

私の関数が別の関数、特にオブジェクトである引数に対して行う呼び出しをテストしようとしています。

問題は、sinon.js がその引数配列で指定されたオブジェクト パラメーターへの参照を格納しているように見えることです。これは当然のことです。ただし、これにより、後でパラメーターが ref によって変更されたときに問題が発生し、関数が呼び出された時点でこれらのパラメーターの見かけの値が変更されます。

このような状況を単体テストする最良の方法は何ですか?

これは不自然な例です:

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?');
});​

この「問題」に関するさまざまなハックを考えることができます。sinon を機能させるためだけに、オブジェクトのクローンを作成したり、製品コードを変更したりする必要のない、よりクリーンなアプローチはありますか?

4

1 に答える 1

7

これに関する Github の議論に関する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
于 2012-10-16T14:09:20.420 に答える