确保Express App在每次Mocha测试之前运行

Has*_*han 19 mocha.js mongoose node.js express superagent

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

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

问题是,在设置Mocha时,我需要确保app.coffee中存在的ExpressJS App在执行任何测试用例之前已成功完成,包括所有异步代码.

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

before (done) ->
  require(__dirname + '/../src/app')
  done()
Run Code Online (Sandbox Code Playgroud)

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

我怎么能这样做?

tma*_*ini 14

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

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;
Run Code Online (Sandbox Code Playgroud)

确保您的配置文件具有不同的环境,如开发,测试,生产设置:

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: {
    // ...
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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();
        });
      });
    });
Run Code Online (Sandbox Code Playgroud)

最后,为了启动整个怪物,你将它包含在你的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"
  }
Run Code Online (Sandbox Code Playgroud)

现在,您可以使用npm test和您的应用程序启动测试套件npm start.

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

  • supertest知道expressjs应用程序何时可以使用?当你的http动词初始化时,你如何保证数据库可以使用? (6认同)
  • `mongoose.connect`阻塞直到数据库准备好了吗?如果是,那么什么是事件('开放'等)? (6认同)
  • 但是db怎么样?AFAIK你必须使用像`mongoose.connection.once('open',callback)`这样的东西然后添加你的路线.这意味着应用程序是异步初始化的.你怎么处理? (4认同)

Beh*_*çar 0

您不需要监听端口来测试您的应用程序。您可以在您的应用程序中使用supertest测试库,应该没问题。

不过,您可能需要连接到数据库或 Redis 客户端。您可以在configure应用程序的方法中执行此操作。由于节点缓存模块,因此您可以在不同的测试模块中调用应用程序模块而无需重新连接。

  • 您确实需要监听端口。您可以允许 supertest [为您做这件事](https://github.com/visionmedia/supertest/blob/199​​506d8dbfe0bb1434fc07c38cdcd1ab4c7c926/lib/test.js#L59)。 (2认同)