javascript node.js unit-testing private mocha

javascript - pruebas unitarias de funciones privadas con mocha y node.js



unit-testing private (6)

Hice un paquete npm para este propósito que podría serle útil: require-from

Básicamente expone métodos no públicos por:

module.testExports = { private_foobar1: private_foobar1, private_foobar2: private_foobar2, ... }

nota: testExports puede ser cualquier nombre válido que desee, excepto las exports por supuesto.

Y desde otro módulo:

var requireFrom = require(''require-from''); var private_foobar1 = requireFrom(''testExports'', ''./path-to-module'').private_foobar1;

Estoy usando mocha para probar la unidad de una aplicación escrita para node.js

Me pregunto si es posible probar las funciones de la unidad que no se han exportado en un módulo.

Ejemplo:

Tengo muchas funciones definidas así en foobar.js

function private_foobar1(){ ... } function private_foobar2(){ ... }

y algunas funciones exportadas como públicas:

exports.public_foobar3 = function(){ ... }

El caso de prueba está estructurado de la siguiente manera:

describe("private_foobar1", function() { it("should do stuff", function(done) { var stuff = foobar.private_foobar1(filter); should(stuff).be.ok; should(stuff).....

Obviamente, esto no funciona, ya que private_foobar1 no se exporta.

¿Cuál es la forma correcta de probar los métodos privados? ¿Tiene mocha algunos métodos incorporados para hacer eso?


Mira el módulo de rewire . Le permite obtener (y manipular) variables y funciones privadas dentro de un módulo.

Entonces, en su caso, el uso sería algo así como:

var rewire = require(''rewire''), foobar = rewire(''./foobar''); // Bring your module in with rewire describe("private_foobar1", function() { // Use the special ''__get__'' accessor to get your private function. var private_foobar1 = foobar.__get__(''private_foobar1''); it("should do stuff", function(done) { var stuff = private_foobar1(filter); should(stuff).be.ok; should(stuff).....


Si el módulo no exporta la función, no puede invocarse mediante código de prueba fuera del módulo. Eso se debe a cómo funciona JavaScript, y Mocha no puede eludir esto por sí mismo.

En los pocos casos en que determiné que probar una función privada es lo correcto, lo que hice fue establecer una variable de entorno que mi módulo verifica para determinar si se está ejecutando en una configuración de prueba o no. Si se ejecuta en la configuración de prueba, entonces exporta funciones adicionales que luego puedo llamar durante la prueba.

La palabra "medio ambiente" se usa libremente aquí. Puede significar verificar process.env o alguna otra cosa que pueda comunicarse con el módulo "ahora lo están probando". Las instancias en las que he tenido que hacer esto estaban en un entorno RequireJS, y he usado module.config para este propósito.


Si prefiere mantenerlo simple, solo exporte los miembros privados, pero claramente separados de la API pública con alguna convención, por ejemplo, prefíquelos con un _ o anótelos bajo un solo objeto privado .

var privateWorker = function() { return 1 } var doSomething = function() { return privateWorker() } module.exports = { doSomething: doSomething, _privateWorker: privateWorker }


Aquí hay un flujo de trabajo realmente bueno para probar sus métodos privados explicado por Philip Walton, un ingeniero de Google en su blog.

Principio

  • Escribe tu código normalmente
  • Vincula tus métodos privados al objeto en un bloque de código separado, márcalo con un _ por ejemplo
  • Rodear ese bloque de código por comentarios de inicio y final

Luego use una tarea de compilación o su propio sistema de compilación (por ejemplo, grunt-strip-code) para despojar a este bloque de las compilaciones de producción.

Las compilaciones de prueba tienen acceso a su API privada, y las compilaciones de producción no.

Retazo

Escribe tu código así:

var myModule = (function() { function foo() { // private function `foo` inside closure return "foo" } var api = { bar: function() { // public function `bar` returned from closure return "bar" } } /* test-code */ api._foo = foo /* end-test-code */ return api }())

Y tus tareas gruñonas como esa

grunt.registerTask("test", [ "concat", "jshint", "jasmine" ]) grunt.registerTask("deploy", [ "concat", "strip-code", "jshint", "uglify" ])

Mas profundo

En un artículo posterior , explica el "por qué" de "probar métodos privados"


Seguí la respuesta de @barwin y verifiqué cómo se pueden hacer las pruebas unitarias con el módulo de recableado . Puedo confirmar que esta solución simplemente funciona.

El módulo debe ser requerido en dos partes: pública y privada. Para funciones públicas, puede hacerlo de forma estándar:

const { public_foobar3 } = require(''./foobar'');

Para ámbito privado:

const privateFoobar = require(''rewire'')(''./foobar''); const private_foobar1 = privateFoobar .__get__(''private_foobar1''); const private_foobar2 = privateFoobar .__get__(''private_foobar2'');

Para saber más sobre el tema, creé un ejemplo de trabajo con pruebas de módulo completo, las pruebas incluyen alcance privado y público.

Para obtener más información, lo invito a consultar el artículo ( https://medium.com/@macsikora/how-to-test-private-functions-of-es6-module-fb8c1345b25f ) que describe completamente el tema, incluye muestras de código.