Estoy tratando de descubrir cómo probar funciones internas (es decir, no exportadas) en nodejs (preferiblemente con mocha o jazmín). Y no tengo idea!
Digamos que tengo un módulo como ese:
function exported(i) {
return notExported(i) + 1;
}
function notExported(i) {
return i*2;
}
exports.exported = exported;
Y la siguiente prueba (moca):
var assert = require('assert'),
test = require('../modules/core/test');
describe('test', function(){
describe('#exported(i)', function(){
it('should return (i*2)+1 for any given i', function(){
assert.equal(3, test.exported(1));
assert.equal(5, test.exported(2));
});
});
});
¿Hay alguna forma de probar la notExported
función de la unidad sin exportarla ya que no está destinada a ser expuesta?
node.js
unit-testing
jasmine
mocha
xavier.seignard
fuente
fuente
Respuestas:
El módulo de recableado es definitivamente la respuesta.
Aquí está mi código para acceder a una función no exportada y probarla usando Mocha.
application.js:
test.js:
fuente
Cannot find module '../../package' from 'node.js'
. ¿Has visto esto?El truco consiste en establecer la
NODE_ENV
variable de entorno en algo asítest
y luego exportarla condicionalmente.Suponiendo que no ha instalado globalmente mocha, podría tener un Makefile en la raíz de su directorio de aplicaciones que contiene lo siguiente:
Este archivo de configuración configura NODE_ENV antes de ejecutar mocha. Luego puede ejecutar sus pruebas de mocha con
make test
en la línea de comando.Ahora, puede exportar condicionalmente su función que generalmente no se exporta solo cuando se ejecutan sus pruebas de mocha:
La otra respuesta sugirió usar un módulo vm para evaluar el archivo, pero esto no funciona y arroja un error que indica que las exportaciones no están definidas.
fuente
EDITAR:
Cargar un módulo usando
vm
puede causar un comportamiento inesperado (por ejemplo, elinstanceof
operador ya no trabaja con objetos que se crean en dicho módulo porque los prototipos globales son diferentes de los utilizados en el módulo cargado normalmenterequire
). Ya no uso la técnica a continuación y en su lugar uso el módulo de recableado . Funciona maravillosamente Aquí está mi respuesta original:Desarrollando la respuesta de Srosh ...
Se siente un poco hacky, pero escribí un simple módulo "test_utils.js" que debería permitirle hacer lo que quiera sin tener exportaciones condicionales en sus módulos de aplicación:
Hay algunas cosas más que se incluyen en el
module
objeto global de un módulo de nodo que también podrían necesitar entrar en elcontext
objeto anterior, pero este es el conjunto mínimo que necesito para que funcione.Aquí hay un ejemplo usando mocha BDD:
fuente
rewire
?Trabajando con Jasmine, traté de profundizar con la solución propuesta por Anthony Mayfield , basada en rewire .
Implementé la siguiente función ( Precaución : aún no se ha probado exhaustivamente, solo se ha compartido como una estrategia posible) :
Con una función como esta, podría espiar tanto los métodos de objetos no exportados como las funciones de nivel superior no exportadas, de la siguiente manera:
Entonces puede establecer expectativas como estas:
fuente
puede crear un nuevo contexto utilizando el módulo vm y evaluar el archivo js en él, algo así como lo hace réplica. entonces tienes acceso a todo lo que declara.
fuente
He encontrado una forma bastante simple que le permite probar, espiar y burlarse de esas funciones internas desde las pruebas:
Digamos que tenemos un módulo de nodo como este:
Si ahora queremos prueba y de espionaje y fingida
myInternalFn
mientras no exportarlo en la producción que tenemos que mejorar el archivo de la siguiente manera:Ahora puede probar, espiar y simular en
myInternalFn
cualquier lugar donde lo usetestable.myInternalFn
y en producción no se exporta .fuente
Esta no es una práctica recomendada, pero si no puede usar
rewire
como lo sugiere @Antoine, siempre puede leer el archivo y usarloeval()
.Encontré esto útil mientras la unidad prueba archivos JS del lado del cliente para un sistema heredado.
Los archivos JS configurarían una gran cantidad de variables globales
window
sin ninguna instrucciónrequire(...)
ymodule.exports
(no había un paquete de módulos como Webpack o Browserify disponible para eliminar estas declaraciones de todos modos).En lugar de refactorizar toda la base de código, esto nos permitió integrar pruebas unitarias en nuestro JS del lado del cliente.
fuente