Я хочу проверить вызов, который моя функция делает для другой функции, особенно аргумента, который является объектом.
Проблема в том, что 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 работать?
strictEquals(blah.otherstuff.firstCall.args[0], expectedFirstCallCoords)
, это не помогло бы против клона. В моем надуманном примере это не проблема, но что, еслиexpectedFirstCallCoords
было введено в функцию/класс? Это было бы очень нежелательно. В лучшем случае, который я вижу в любом случае, это то, что ему нужно будет хранить как исходные ссылки на объекты, так и клонированные объекты, и это сбивает с толку. - person Adam Terlson   schedule 15.10.2012equal
плохой практикой. Учтите, когда вы проверяете свои значения, которые проходитequal(true, 1);
. - person Adam Terlson   schedule 16.10.2012equal
со знанием того, что это действительно правда, это, конечно, именно то, для чего оно нужно! Я просто люблю откровенность :). Кроме того, то, что я тестировал в своемequal(true, 1)
, было не логическим, а вместо этого1
, поэтому ожидание целого числа и прохождение теста, когда я фактически получил логическое значение (или строку), кажется мне неправильным. Для большинства логических случаев, когда меня интересует только правдивость, я используюok()
. Чистый результат, теперь, когда я думаю об этом, я никогда не используюequal
. :) Но это всего лишь, признаюсь, личное предпочтение. Хорошая дискуссия! - person Adam Terlson   schedule 16.10.2012