tutorial node modulos funciones exports exportar example ejemplos javascript node.js mocking

javascript - modulos - Cómo probar un módulo node.js que requiere otros módulos



node js tutorial (6)

¡Tu puedes ahora!

proxyquire que se encargará de anular el requerimiento global dentro de su módulo mientras lo está probando.

Esto significa que no necesita cambios en su código para inyectar simulacros para los módulos requeridos.

Proxyquire tiene una API muy simple que permite resolver el módulo que está tratando de probar y pasar burlas / stubs para los módulos requeridos en un simple paso.

@Raynos tiene razón en que, tradicionalmente, tenía que recurrir a soluciones no muy ideales para lograr eso o hacer un desarrollo de abajo hacia arriba en su lugar

Que es la razón principal por la que creé proxyquire - para permitir el desarrollo impulsado por prueba de arriba hacia abajo sin ningún tipo de molestia.

Eche un vistazo a la documentación y los ejemplos para evaluar si se ajusta a sus necesidades.

Este es un ejemplo trivial que ilustra el quid de mi problema:

var innerLib = require(''./path/to/innerLib''); function underTest() { return innerLib.doComplexStuff(); } module.exports = underTest;

Estoy tratando de escribir una prueba unitaria para este código. ¿Cómo puedo burlarme del requisito de innerLib sin innerLib la función require completo?

EDITAR: Así que este soy yo tratando de burlarme de las necesidades globales y descubrir que no funcionará ni siquiera para hacer eso:

var path = require(''path''), vm = require(''vm''), fs = require(''fs''), indexPath = path.join(__dirname, ''./underTest''); var globalRequire = require; require = function(name) { console.log(''require: '' + name); switch(name) { case ''connect'': case indexPath: return globalRequire(name); break; } };

El problema es que la función de require dentro del archivo underTest.js en realidad no ha sido burlada. Todavía apunta a la función global require . Entonces parece que solo puedo burlarme de la función de require dentro del mismo archivo que estoy haciendo la burla. Si utilizo la función global require para incluir cualquier cosa, incluso después de haber anulado la copia local, los archivos que se requieren seguirán teniendo la referencia global require .


La burla require sentirse como un truco desagradable para mí. Personalmente, intentaría evitarlo y refactorizar el código para hacerlo más comprobable. Hay varios enfoques para manejar dependencias.

1) pasar dependencias como argumentos

function underTest(innerLib) { return innerLib.doComplexStuff(); }

Esto hará que el código sea comprobable universalmente. La desventaja es que debe pasar dependencias, lo que puede hacer que el código parezca más complicado.

2) implementar el módulo como una clase, luego usar métodos / propiedades de clase para obtener dependencias

(Este es un ejemplo artificial, donde el uso de clase no es razonable, pero transmite la idea) (ejemplo ES6)

const innerLib = require(''./path/to/innerLib'') class underTestClass { getInnerLib () { return innerLib } underTestMethod () { return this.getInnerLib().doComplexStuff() } }

Ahora puede getInnerLib fácilmente el método getInnerLib para probar su código. El código se vuelve más detallado, pero también más fácil de probar.


No puedes. Debe construir su conjunto de pruebas unitarias para que primero se prueben los módulos más bajos y luego se prueben los módulos de nivel superior que requieren módulos.

También debes asumir que cualquier código de terceros y node.js están bien probados.

Supongo que verá que en un futuro próximo aparecerán marcos burlones que sobrescribirán global.require

Si realmente debe inyectar un simulacro, puede cambiar su código para exponer el alcance modular.

// underTest.js var innerLib = require(''./path/to/innerLib''); function underTest() { return innerLib.toCrazyCrap(); } module.exports = underTest; module.exports.__module = module; // test.js function test() { var underTest = require("underTest"); underTest.__module.innerLib = { toCrazyCrap: function() { return true; } }; assert.ok(underTest()); }

Tenga en cuenta que esto expone el .__module en su API y cualquier código puede acceder al alcance modular bajo su propio riesgo.


Puedes usar la biblioteca de mockery :

describe ''UnderTest'', -> before -> mockery.enable( warnOnUnregistered: false ) mockery.registerMock(''./path/to/innerLib'', { doComplexStuff: -> ''Complex result'' }) @underTest = require(''./path/to/underTest'') it ''should compute complex value'', -> expect(@underTest()).to.eq ''Complex result''


Una mejor opción en este caso es simular los métodos del módulo que se devuelve.

Para bien o para mal, la mayoría de los módulos node.js son singletons; dos pedazos de código que requieren () que el mismo módulo obtenga la misma referencia a ese módulo.

Puede aprovechar esto y usar algo como sinon para burlarse de los elementos que se requieren. mocha prueba de mocha sigue:

// in your testfile var innerLib = require(''./path/to/innerLib''); var underTest = require(''./path/to/underTest''); var sinon = require(''sinon''); describe("underTest", function() { it("does something", function() { sinon.stub(innerLib, ''toCrazyCrap'', function() { // whatever you would like innerLib.toCrazyCrap to do under test }); underTest(); sinon.assert.calledOnce(innerLib.toCrazyCrap); // sinon assertion innerLib.toCrazyCrap.restore(); // restore original functionality }); });

Sinon tiene una buena integración con chai para hacer aserciones, y escribí un módulo para integrar sinon con mocha para facilitar la limpieza de espías / trozos (para evitar la contaminación de prueba).

Tenga en cuenta que underTest no se puede burlar de la misma manera, ya que underTest solo devuelve una función.


Yo uso el mock-require . Asegúrese de definir sus burlas antes de require que se pruebe el módulo.