Sinon no actualiza el contador de llamadas cuando la función que está simulada se llama a través de una variable local.
Tengo esta función writeToFile la cual agrega o escribe según el argumento append. El appendFile y writeFile son de los módulos fs que estoy tratando de agregar a mis pruebas unitarias.
El problema en el siguiente código es que, al probarlo y crear stubs para appendFile y writeFile de fs, el contador de llamadas (callCount) no se incrementa si asigno las funciones append y write a una variable local func. Si solo llamo estas funciones directamente agregando una condición, las pruebas funcionan bien pero serían líneas de código adicionales y feas (según algunas personas).
Sería bueno si alguien pudiera explicar este comportamiento de sinon con la asignación de función a una variable local y si hay una solución sin cambiar la función en utils.js
Fragmento de código de utils.js:
export async function writeToFile(path, data, append) {
const func = append ? fs.appendFile : fs.writeFile;
return func(path, data, (err) => {
if (err) { logger.error(err); }
});
}
Fragmento de código de test.js:
it('Write to file', async () => {
const append = sinon.stub(fs, 'appendFile');
const write = sinon.stub(fs, 'writeFile');
await writeToFile('path', 'buffer', false);
expect(append.callCount).to.equal(0);
expect(write.callCount).to.equal(1);
await writeToFile('path', 'buffer', true);
expect(append.callCount).to.equal(1);
expect(write.callCount).to.equal(1);
});
aquí puedes ver la imagen.
davy.ai
El problema es que la variable
func
en la funciónwriteToFile
se le asigna una referencia afs.appendFile
ofs.writeFile
, pero los stubsappend
ywrite
se crean antes de que se llame a la función, por lo que no tienen una referencia a la función correcta en el momento en que se llaman. Es por eso que elcallCount
no se incrementa cuando se utiliza la variablefunc
.Una solución a este problema es usar el método
callsFake
del stub para reemplazar la implementación de la variablefunc
con el stub, de la siguiente manera:Esto reemplazará la implementación de
func
con el stub, que seguirá correctamente el número de veces que se llama.Otra solución es pasar el módulo
fs
como argumento a la funciónwriteToFile
, para que los stubs puedan crearse con la referencia correcta afs.appendFile
ofs.writeFile
. Esto requeriría cambiar la firma de la funciónwriteToFile
, lo cual puede que no sea deseable.En general, el uso del método
callsFake
es una solución simple y efectiva a este problema.