unitarios tutorial test spec nodejs node español before async javascript node.js asynchronous promise mocha

javascript - tutorial - nodejs test



Ejecutar código asíncrono antes de la prueba completa de mocha (4)

Me gustaría mover la lógica async dentro de la llamada. Ser demasiado sofisticado con las pruebas unitarias es un olor codificado y probablemente irrite a otros desarrolladores cuando no solo tienen que depurar y corregir las pruebas fallidas, sino que deben depurar y corregir las pruebas que ni siquiera están definidas y se están ejecutando porque el sofisticado código de configuración tiene errores. . Intenta no ir allí.

var assert = require(''assert'') var Promise = require(''bluebird'') /* global describe, it*/ var fn = function(value) { return value + '' '' + ''pancake'' } function getTests() { return Promise.resolve(''kitty pancake'') .delay(500) .then(function(value) { return [ { ''arg'': ''kitty'', ''expect'': value }, { ''arg'': ''doggy'', ''expect'': ''doggy pancake'' } ] }) } describe(''example'', function() { it(''should handle many things'', function(done) { getTests().then(function(tests) { tests.forEach(function(test) { var value = fn(test.arg) assert.equal(value, test.expect, ''should return '' + test.expect) }) done() }) }) })

Estoy buscando una forma de ejecutar el código asíncrono antes de la prueba completa de mocha.

Aquí hay un ejemplo de una prueba que usa una matriz de argumentos y expectativas, y recorre todos los elementos de esta matriz para producir aserciones de funciones.

var assert = require(''assert'') /* global describe, it*/ var fn = function (value) { return value + '' '' + ''pancake'' } var tests = [ { ''arg'': ''kitty'', ''expect'': ''kitty pancake'' }, { ''arg'': ''doggy'', ''expect'': ''doggy pancake'' }, ] describe(''example'', function () { tests.forEach(function (test) { it(''should return '' + test.expect, function (){ var value = fn(test.arg) assert.equal(value, test.expect) }) }) })

Ahora, mi pregunta es cómo funcionaría esto si el valor de las pruebas proviniera de una promesa, como esta:

var assert = require(''assert'') var Promise = require(''bluebird'') /* global describe, it*/ var fn = function (value) { return value + '' '' + ''pancake'' } function getTests () { return Promise.resolve(''kitty pancake'') .delay(500) .then(function (value) { return [ { ''arg'': ''kitty'', ''expect'': value }, { ''arg'': ''doggy'', ''expect'': ''doggy pancake'' } ] }) } getTests().then(function (tests) { describe(''example'', function () { tests.forEach(function (test) { it(''should return '' + test.expect, function (){ var value = fn(test.arg) assert.equal(value, test.expect) }) }) }) })

también intenté:

describe(''example'', function () { getTests().then(function (tests) { tests.forEach(function (test) { it(''should return '' + test.expect, function (){ var value = fn(test.arg) assert.equal(value, test.expect) }) }) }) })

Sin embargo, en este ejemplo, ninguna de las pruebas se ejecuta porque mocha no reconoce la declaración de descripción porque está dentro de una promesa.

before / beforeEach no hará nada para ayudar con una prueba en el formato de todos modos a menos que fuera un hook beforeTest que proporcionaría mocha con el conocimiento de que hay una operación asincrónica que debe ejecutarse antes de la prueba completa.


No estoy seguro de si hay alguna manera fácil de hacerlo, pero podrías intentar ejecutar Mocha programáticamente .

Aquí hay una pequeña versión sucia de cómo podría verse esto, solo para mostrar la idea.

data.js

var Promise = require(''bluebird'') module.exports.tests = [] function getTests () { return Promise.resolve(''kitty pancake'') .delay(500) .then(function (value) { module.exports.tests = [ { ''arg'': ''kitty'', ''expect'': value }, { ''arg'': ''doggy'', ''expect'': ''doggy pancake'' } ] }) } module.exports.getTests = getTests

test-launcher.js

var Mocha = require(''mocha''), fs = require(''fs''), path = require(''path'') // First, you need to instantiate a Mocha instance. var mocha = new Mocha() // Then, you need to use the method "addFile" on the mocha // object for each file. // Here is an example: fs.readdirSync(''test'').filter(function(file){ // Only keep the .js files return file.substr(-3) === ''.js'' }).forEach(function(file){ // Use the method "addFile" to add the file to mocha mocha.addFile( path.join(''test'', file) ) }) // make sure your tests are loaded before running the tests require(''./data'').getTests().then(function () { // Now, you can run the tests. mocha.run(function(failures){ process.on(''exit'', function () { process.exit(failures) }) }) })

test/index.js

var assert = require(''assert'') var tests = require(''../data'').tests var fn = function (value) { return value + '' '' + ''pancake'' } describe(''test'', function () { describe(''example'', function () { tests.forEach(function (test) { it(''should return '' + test.expect, function (){ var value = fn(test.arg) assert.equal(value, test.expect) }) }) }) })

A continuación, puede ejecutar sus silencios ejecutando test-launcher.js .


Como alternativa al método de Daniel Pérez también puede usar el interruptor de línea de comando --delay e iniciar las pruebas en la primera llamada de run() . Al retrasar la run() forma asíncrona, puede registrar describe sy es asíncrono de antemano. Sin embargo, tenga en cuenta que solo puede llamar a run() una vez, es decir, solo en un archivo de prueba. Por lo tanto, he creado un corredor de prueba asíncrono en ./test/ y cada prueba asíncrona en ./testAsync/ :

// ./test/asyncRunner.js "use strict"; const allAsyncPaths = [ "test-featureA", "test-featureB", ].map(a => "../testAsync/" + a); const allAsyncTestFunctions = allAsyncPaths.map(require); Promise.resolve({ }).then(function() { const allPromises = allAsyncTestFunctions.map(a => a()); return Promise.all(allPromises); }).then(function() { run(); // mocha waits for run() because of --delay flag }).catch(function(err) { console.error(err); });

y

// ./testAsync/test-featureA.js "use strict"; function asyncTestRegistrator() { return Promise.resolve({ }).then(function() { return getTestsAsync(); }).then(function(tests) { describe(''example'', function () { tests.forEach(function (test) { it(''should return '' + test.expect, function (){ var value = fn(test.arg); assert.equal(value, test.expect); }); }); }); } module.exports = asyncTestRegistrator;


Usaría la opción async / await with delay como a continuación:

setTimeout(async () => { //get tests async const tests = await getTests() describe(''example'', async () => { tests.forEach((test) => { it(`test name: ${test.name} `, () => { console.log(test.name) }) }) }) run() }, 1000)