test node node.js express mongoose mocha superagent

node.js - node - sinon js



Asegurar que la aplicaciĆ³n Express se ejecute antes de cada prueba Mocha (6)

Básicamente necesitas dos cosas que debes hacer.

  1. Asegúrese de que la base de datos se conecta antes de que el servidor escuche
  2. Asegúrese de que la aplicación se inicie antes de ejecutar las pruebas.

El marco ya tiene una forma de manejar esto mediante el uso de eventos.

Agregue esto a su conexión de base de datos, que le indica a mongoose que emita "listo" cuando haya terminado de conectarse.

mongoose.connection.once(''open'', function() { // All OK - fire (emit) a ready event. console.log(''Connected to MongoDB''); app.emit(''ready''); });

Luego indique a Express que espere a que esté "listo" antes de escuchar. Cuando está hecho, emite: ''appStarted''.

app.on(''ready'', function() { app.listen(PORT, function(){ console.log("Server listing on port:",PORT); app.emit("appStarted"); }); });

Todo esto es una buena práctica, aparte de Mocha, para asegurarse de que su servidor se inicie sin problemas. Para finalizar la integración de Mocha en tu antes (me gusta usar Promesas):

before(function() { return new Promise((resolve,reject) => { app.on("appStarted", function(){ return resolve(); }); }); });

Estoy trabajando en el desarrollo de una API REST utilizando ExpressJS, NodeJS, Mongoose y Mocha.

El problema es que tengo un archivo app.coffee, que es el responsable de configurar ExpressJS y de conectarme a Mongoose. La forma en que lo he configurado es que Mongoose se conecta primero y, si eso se logra, se inicia la aplicación ExpressJS.

El problema es que al configurar Mocha, debo asegurarme de que la aplicación ExpressJS existente en app.coffee se inicie con éxito, incluido todo el código asíncrono antes de ejecutar cualquier testcase.

Para eso, creé un test_helper.coffee y coloqué el siguiente código en él, pero los testcases comienzan su ejecución incluso si el código en app.coffee no se ha completado completamente, lo que realmente tiene sentido:

before (done) -> require(__dirname + ''/../src/app'') done()

En pocas palabras, quiero asegurarme de que la aplicación ExpressJS haya completado completamente su configuración antes de ejecutar cualquier testcase.

¿Como puedo hacer eso?


El método app.listen toma una devolución de llamada que se ejecuta cuando todo está listo. Por lo tanto, necesitas poder pasar la devolución de llamada hecha allí. Algo como

before (done) -> var app = require(__dirname + ''/../src/app'') app.listen(3000, done)


Llego tarde a la fiesta, pero encontré que la mejor manera de configurar mi suite de prueba mocha para una aplicación Express es hacer que mi archivo app.js o server.js exporte el objeto de la aplicación, como este:

var mongoose = require(''mongoose''); var express = require(''express''); require(''express-mongoose''); var env = process.env.NODE_ENV || ''development''; var config = require(''./config/config'')[env]; var models = require(''./app/models''); var middleware = require(''./app/middleware''); var routes = require(''./app/routes''); var app = express(); app.set(''port'', process.env.PORT || config.port || 3000); app.set(''views'', __dirname + ''/app/views''); app.set(''view engine'', ''jade''); // database mongoose.connect(config.db); // middleware middleware(app); // Application routes routes(app); app.listen(app.get(''port'')); console.log(''Express server listening on port '' + app.get(''port'')); // export app so we can test it exports = module.exports = app;

asegúrese de que su archivo de configuración tenga diferentes entornos como desarrollo, prueba, configuración de producción:

var path = require(''path''); var rootPath = path.normalize(__dirname + ''/..''); module.exports = { development: { db: ''mongodb://localhost/my_dev_db'', port: 3000 }, test: { db: ''mongodb://localhost/my_test_db'', port: 8888 }, production: { // ... } }

Luego, en sus archivos de prueba, puede seguir adelante y requerir su aplicación, que se conectará a la base de datos correcta y al puerto correcto:

var should = require(''chai'').should(); var request = require(''supertest''); var mongoose = require(''mongoose''); var app = require(''../app''); var agent = request.agent(app); var User = mongoose.model(''User''); // get users describe(''GET /api/users'', function() { it(''returns users as JSON'', function(done) { agent .get(''/api/users'') .expect(200) .expect(''Content-Type'', /json/) .end(function(err, res) { if (err) return done(err); res.body.should.have.property(''users'').and.be.instanceof(Array); done(); }); }); });

Y finalmente, para iniciar todo el monstruo, incluya esto en su package.json (asegúrese de tener nodemon y mocha en sus DevDependencies):

"scripts": { "start": "NODE_ENV=development ./node_modules/.bin/nodemon app.js", "test": "NODE_ENV=test ./node_modules/.bin/mocha --reporter spec test/**.js" }

Ahora puede iniciar su suite de pruebas con npm test y su aplicación con npm start .

¡Espero eso ayude! ps: la mayoría de las cosas que aprendí al observar este increíble ejemplo: https://github.com/madhums/node-express-mongoose-demo


Me encontré con el mismo problema al usar jasmine / supertest para probar mi aplicación Express. Resolví el problema emitiendo cuando la aplicación estaba lista y luego solo ejecutaba mis pruebas. Aquí está mi estructura de directorios

- server.js - spec - setup.spec.js - test.spec.js

En server.js siempre que su servidor esté configurado y esté listo para ejecutar sus pruebas, agregue app.emit(''started''); . ¡Y asegúrate de exportar tu aplicación! En setup.spec.js puede ver el evento que se emitirá.

server.js

const express = require(''express''); const app = express(); module.exports = app; // for testing setTimeout(() => { app.listen(process.env.PORT || 3000); });

setup.spec.js

const server = require(''../index''); beforeAll(done => server.on(''started'', done));

test.spec.js

const request = require(''supertest''); const server = require(''../index''); describe(''test'', () => { it(''test server works'', done => { request(server).get(''/test'').expect(200); }); });

La misma idea debería funcionar para mocha también. Aquí hay un artículo explicando esto para mocha . Solo debes cambiar before beforeAll a before .


No necesitas escuchar un puerto para probar tu aplicación. Puede usar la biblioteca de pruebas de supertest con su aplicación y debería estar bien.

Sin embargo, es probable que necesites conectarte a una base de datos o al cliente redis Puedes hacer esto en el método de configure de tu aplicación. Como los nodos almacenan en caché los módulos, puede requerir un módulo de aplicación en diferentes módulos de prueba sin tener que volver a conectarse.


Puede haber una forma más directa, pero fui a Grunt para automatizar mis pruebas funcionales. Hay un plugin express y mocha para alcanzar tu meta. Mi archivo de gruñidos

''use strict''; module.exports = function (grunt) { grunt.initConfig({ express: { options: {} , test: { options: { script: ''./app.js'' } } } , simplemocha: { options: { globals: [''should''] , timeout: 8000 , ignoreLeaks: false , ui: ''bdd'' , reporter: ''tap'' } , all: { src: [''tests/*.test.js''] } } }) grunt.loadNpmTasks(''grunt-express-server'') grunt.loadNpmTasks(''grunt-simple-mocha'') grunt.registerTask(''default'', [''express:test'', ''simplemocha'', ''express:test:stop'']) }

bono: agregue ''gruñido'' como un gancho de pre-confirmación de git. De esta manera no puedes comprometerte sin pasar todas las pruebas.