not - ¿Puede sinon stub withArgs coincidir con algunos pero no con todos los argumentos?
sinon spy not called (4)
Solución
withArgs
se
puede usar para
withArgs
algunos pero no todos los argumentos.
Específicamente,
method.get.withArgs(25)
verificará
solo el primer argumento
.
Corrección
Esto es incorrecto:
withArgs()
coincide con todos los argumentos
Detalles
Cuando se
withArgs
, recuerda los argumentos que se pasaron
here
como
matchingArguments
.
Luego, cuando se llama al
stub
se obtienen todas las falsificaciones correspondientes
here
.
matchingFakes
se llama sin un segundo parámetro, por lo que devuelve todas las falsificaciones que tienen
matchingArguments
que coinciden con los argumentos pasados al
stub
comienzan en el índice 0 hasta la longitud de
matchingArguments
.
Esto significa que un falso coincidirá cuando sus argumentos
matchingArguments
coincidan con el comienzo de los argumentos pasados,
incluso si hay argumentos adicionales
.
Las falsificaciones coincidentes se
ordenan por
matchingArguments.length
y la que coincide con la mayoría de los argumentos es la que se
invoked
.
La siguiente prueba confirma este comportamiento y pasa con la versión
1.1.0
de
sinon
de hace 7 años, la versión
1.14.0
desde el momento en que se hizo esta pregunta y la versión actual
6.3.5
:
import * as sinon from ''sinon'';
test(''withArgs'', () => {
const stub = sinon.stub();
stub.withArgs(25).returns(''first arg is 25!'');
stub.returns(''default response'');
expect(stub(25)).toBe(''first arg is 25!''); // SUCCESS
expect(stub(25, function () { }, function () { })).toBe(''first arg is 25!''); // SUCCESS
expect(stub(10, function () { }, function () { })).toBe(''default response''); // SUCCESS
});
Tengo una función que estoy tropezando que se llama con múltiples argumentos. Quiero verificar solo el primer argumento . El resto es función de devolución de llamada, por lo que quiero dejarlos solos. Por lo tanto, podría tener las siguientes 2 llamadas, usando ajax como ejemplo:
method.get = sinon.stub();
method.get(25,function(){/* success callback */},function(){/* error callback */});
method.get(10,function(){/* success callback */},function(){/* error callback */});
No puedo usar
method.get.calls...
porque entonces no diferencia entre el primer
get(25)
y el segundo
get(10)
.
Pero si utilizo
method.get.withArgs(25).calls...
entonces tampoco coincide, porque
withArgs()
coincide con
todos los
argumentos, lo cual no coincide (y nunca podría, con devoluciones de llamada como esa).
¿Cómo hago para que los sinon stubs verifiquen y establezcan respuestas basadas solo en el primer argumento?
Si solo desea verificar el primer argumento, puede usar
method.get.withArgs(25).calledOnce
o
method.get.calledWith(25)
este método funciona muy bien con los espías si desea verificar solo un argumento entre muchos
it(''should check only first argument'', function ():void {
myFunction(''foo'', ''bar'', baz'');
expect(myFunctionSpy.firstCall.args[0]).to.equal(''foo'');
});
Sin embargo, no entiendo por qué estás usando talones aquí. Si solo desea verificar cómo se llama la función, debe usar un espía. Si desea verificar cómo se llama Y cambiar su comportamiento (por ejemplo: bloquear llamadas ajax), entonces debe usar un simulacro.
Los simulacros de Sinon tienen su propia forma de verificar las cosas. La única forma que conozco para su caso sería usar sinon.match.many para los argumentos que no desea verificar:
it(''should check only first argument'', async function (): Promise<void> {
mock.expects(''myFunction'').withExactArgs(''foo'', sinon.match.any, sinon.match.any).returns(''foo'');
await myFunction(''foo'', ''bar'', baz'');
mock.verify();
});
mock.verify () procederá a la prueba Y restablecerá el simulacro para otras pruebas, en caso de usar un espía o un trozo, debe hacerlo manualmente con restore () o reset () después de cada prueba
PD: perdón por la sintaxis de TypeScript aquí: p
https://sinonjs.org/releases/latest/matchers/#sinonmatchany
Puedes usar sinon.match.any:
method.get.withArgs(25, sinon.match.any, sinon.match.any);