确保快速应用程序在每个摩卡testing之前运行

我正在使用ExpressJS,NodeJS,Mongoose和Mocha开发REST API。

问题是我有一个app.coffee文件,负责设置ExpressJS并连接到Mongoose。 我设置的方式是,首先连接Mongoose,如果通过,则启动ExpressJS App。

问题是,在设置Mocha时,我需要确保app.coffee中存在的ExpressJS App在执行任何testing用例之前已经成功启动,包括所有asynchronous代码。

为此,我创build了一个test_helper.coffee,并在其中放置了下面的代码,但是,即使app.coffee中的代码还没有完全完成它的执行,testing用例也会开始执行,这实际上是有意义的:

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

简而言之,我想确保ExpressJS应用程序在执行任何testing用例之前已完全完成设置。

我怎么能做到这一点?

我迟到了,但我发现为快速应用程序设置我的mochatesting套件的最好方法是使我的app.js或server.js文件导出应用程序对象,如下所示:

 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; 

确保你的configuration文件有不同的环境,如开发,testing,生产设置:

 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: { // ... } } 

然后在你的testing文件中,你可以继续,并要求你的应用程序,它将连接到正确的数据库和正确的端口:

 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(); }); }); }); 

最后,启动整个怪物,将其包含在package.json (确保devDependencies中有nodemon和mocha):

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

现在你可以用npm test和你的应用程序启动你的testing套件。

希望能帮助到你! ps:我从这个惊人的例子中学到的大部分东西: https : //github.com/madhums/node-express-mongoose-demo

你不需要听一个端口来testing你的应用程序。 您可以使用超级testing库与您的应用程序,它应该没问题。

你可能需要连接到数据库或redis客户端。 你可以在你的应用程序的configure方法中做到这一点。 由于节点caching模块,因此可以在不同的testing模块中要求应用模块而不重新连接。

可能有一个更直接的方法,但我去Grunt自动化我的functiontesting。 有一个快递和摩卡插件来达到你的目标。 我的gruntfile:

 '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']) } 

奖金:添加“grunt”作为git pre-commit钩子。 这样你不能不通过所有的testing

我遇到了同样的问题,同时使用茉莉花/ supertest来testing我的快递应用程序。 我通过在应用程序准备就绪时发出问题来解决问题,之后才运行我的testing。 这是我的目录结构

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

server.js当你的服务器设置好了,你准备好运行你的testing时,添加app.emit('started'); 。 并确保导出您的应用程序! 在setup.spec.js你可以观察事件的发射。

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); }); }); 

同样的想法也适用于摩卡。 这是一篇关于摩卡的文章 。 你应该改变before

app.listen方法需要一个callback,当一切准备就绪时运行。 所以,你需要能够将完成的callback传递给那里。 就像是

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