javascript - ejemplos - i html
¿Cómo probar múltiples llamadas a la misma función con diferentes parámetros? (2)
Supongo que tengo una función como esta:
function foo () {
obj.method(1);
obj.method(2);
obj.method(3);
}
Para probarlo quiero hacer 3 pruebas (usando Mocha TDD y Sinon):
test(''medthod is called with 1'', function () {
var expectation = sinon.mock(obj).expects(''method'').once().withExactArgs(1);
foo();
expectation.verify();
});
test(''medthod is called with 2'', function () {
var expectation = sinon.mock(obj).expects(''method'').once().withExactArgs(2);
foo();
expectation.verify();
});
test(''medthod is called with 3'', function () {
var expectation = sinon.mock(obj).expects(''method'').once().withExactArgs(3);
foo();
expectation.verify();
});
El uso de este sistema sinon falla con el mensaje de "llamada inesperada" en cada prueba.
Lo he resuelto uniendo las pruebas de árbol en una:
test(''medthod is called with 1, 2 and 3'', function () {
var mock = sinon.mock(obj);
mock.expects(''method'').once().withExactArgs(1);
mock.expects(''method'').once().withExactArgs(2);
mock.expects(''method'').once().withExactArgs(3);
foo();
mock.verify();
});
Pero quiero tener tres pruebas y no una con tres afirmaciones / expectativas.
¿Cómo se puede lograr esto?
Como siempre, cuando hay algo extraño en una prueba, el problema está en el código que se está probando .
En este caso sufrimos de acoplamiento. Actualmente la función tiene dos responsabilidades:
- Decidir los datos a utilizar.
- Llama al método con los datos.
Para resolver esto, debemos dividir las responsabilidades en dos funciones / objetos / clases y luego probar cada una por separado. Por ejemplo, una posibilidad podría ser:
La primera función (una que genera y devuelve los datos) se probaría verificando que los datos devueltos coincidan con nuestras expectativas.
La segunda función (la nuestra original) tendría una prueba de verificación de que llama al generador de datos, luego una prueba de que envía los datos correctamente a la función esperada y una tercera que comprueba que llama a las funciones tantas veces como sea necesario. los datos.
El código sería algo como esto:
function foo() {
dataGenerator.generate().forEach(function (item) {
obj.method(item);
})
}
dataGenerator.generate = function () {
return [1,2,3];
};
Y las pruebas:
test(''generateData is called'', function () {
var expectation = sinon.mock(dataGenerator).expects(''generate'').once();
foo();
expectation.verify();
});
test(''method is called with the correct args'', function () {
var expectedArgs = 1;
sinon.stub(dataGenerator, "generate").returns([expectedArgs]);
var expectation = sinon.mock(obj).expects(''method'').once().withExactArgs(expectedArgs);
foo();
expectation.verify();
});
test(''method is called as many times as the amount of data'', function () {
sinon.stub(dataGenerator, "generate").returns([1,2]);
var expectation = sinon.mock(obj).expects(''method'').twice();
foo();
expectation.verify();
});
test(''dataGenerator.generate returns [1,2,3]'', function () {
var expected = [1,2,3];
var result = dataGenerator.generate();
assert.equal(result, expected)
});
Tenga en cuenta que la tercera prueba solo verifica la cantidad de veces que se llama al método. La segunda prueba ya ha verificado que los datos se pasan correctamente y la cuarta prueba los datos en sí.
Esta es una versión hinchada, pero esta solución podría funcionar. No estoy seguro de si todavía lo necesitas, pero lo estoy agregando aquí. http://jsfiddle.net/reyuto/jhkL7j34/
obj = {
method: function (param) {}
};
function foo() {
obj.method(1);
obj.method(2);
obj.method(3);
}
mock = sinon.mock(obj);
QUnit.test(''method is called with 1'', function () {
var expectation1 = mock.expects(''method'').once().withExactArgs(1);
var expectation2 = mock.expects(''method'').atLeast(2);
foo();
expectation1.verify();
expectation2.verify();
});
QUnit.test(''method is called with 2'', function () {
var expectation1 = mock.expects(''method'').atLeast(1);
var expectation2 = mock.expects(''method'').once().withExactArgs(2);
var expectation3 = mock.expects(''method'').atLeast(1);
foo();
expectation1.verify();
expectation2.verify();
expectation3.verify();
});
QUnit.test(''method is called with 3'', function () {
var expectation1 = mock.expects(''method'').once().withExactArgs(3);
var expectation2 = mock.expects(''method'').atLeast(2);
foo();
expectation1.verify();
expectation2.verify();
});