Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 确保在每次摩卡测试前运行Express应用程序_Node.js_Express_Mongoose_Mocha.js_Superagent - Fatal编程技术网

Node.js 确保在每次摩卡测试前运行Express应用程序

Node.js 确保在每次摩卡测试前运行Express应用程序,node.js,express,mongoose,mocha.js,superagent,Node.js,Express,Mongoose,Mocha.js,Superagent,我正在使用ExpressJS、NodeJS、Mongoose和Mocha开发restapi 问题是我有一个app.coffee文件,负责设置ExpressJS并连接到Mongoose。我的设置方式是先连接Mongoose,如果连接成功,然后启动ExpressJS应用程序 问题是,在设置Mocha时,我需要确保App.coffee中存在的ExpressJS应用程序在执行任何测试用例之前完全启动,包括所有异步代码 为此,我创建了一个test_helper.coffee并在其中放置了以下代码,但是,即

我正在使用ExpressJS、NodeJS、Mongoose和Mocha开发restapi

问题是我有一个app.coffee文件,负责设置ExpressJS并连接到Mongoose。我的设置方式是先连接Mongoose,如果连接成功,然后启动ExpressJS应用程序

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

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

before (done) ->
  require(__dirname + '/../src/app')
  done()
简而言之,我想确保ExpressJS应用程序在执行任何测试用例之前已经完全完成了安装


我该怎么做呢?

您不需要监听端口来测试应用程序。您可以在应用程序中使用测试库,它应该是正常的


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

可能有一种更简单的方法,但我去Grunt自动化了我的功能测试。有一个express和mocha插件可以实现您的目标。我的Grunfile:

'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预提交挂钩。通过这种方式,您无法在未通过所有测试的情况下提交

我迟到了,但我发现为express应用程序设置摩卡测试套件的最佳方法是让我的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;
确保您的配置文件具有不同的环境,如开发、测试、生产设置:

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: {
    // ...
  }
}
然后,在您的测试文件中,您可以继续并要求您的应用程序连接到正确的db和正确的端口:

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();
        });
      });
    });
最后,要启动整个monster,您需要在
package.json
中包含它(确保在您的devdependency中包含nodemon和mocha):

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

希望有帮助! ps:我从这个惊人的例子中学到的大部分东西:

我在使用jasmine/supertest测试我的express应用程序时遇到了同样的问题。我解决了这个问题,在应用程序准备就绪时发出警报,然后才运行我的测试。这是我的目录结构

- server.js
- spec
    - setup.spec.js
    - test.spec.js
server.js
中,当您的服务器已设置且准备好运行测试时,添加
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);
});
const server = require('../index');

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

describe('test', () => {
    it('test server works', done => {
        request(server).get('/test').expect(200);
     });
});
setup.spec.js

const express = require('express');
const app = express();
module.exports = app; // for testing

setTimeout(() => {
    app.listen(process.env.PORT || 3000);
});
const server = require('../index');

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

describe('test', () => {
    it('test server works', done => {
        request(server).get('/test').expect(200);
     });
});
测试规范js

const express = require('express');
const app = express();
module.exports = app; // for testing

setTimeout(() => {
    app.listen(process.env.PORT || 3000);
});
const server = require('../index');

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

describe('test', () => {
    it('test server works', done => {
        request(server).get('/test').expect(200);
     });
});
同样的想法也适用于摩卡咖啡。您只需将
beforeAll
更改为
before

该方法接受一个在一切就绪时运行的回调。因此,您需要能够在那里传递done回调。差不多

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

基本上,你需要做两件事

  • 确保在服务器侦听之前数据库已连接
  • 在运行测试之前,请确保应用程序已启动
  • 框架已经有了一种通过使用事件来处理此问题的方法

    将其添加到数据库连接中,这将指示mongoose在连接完成时发出“ready”

    mongoose.connection.once('open', function() { 
       // All OK - fire (emit) a ready event. 
       console.log('Connected to MongoDB');
       app.emit('ready'); 
    });
    
    然后指示express等待“就绪”,然后再收听。完成后,它会发出:“appStarted”

    app.on('ready', function() { 
        app.listen(PORT, function(){ 
            console.log("Server listing on port:",PORT); 
            app.emit("appStarted");
        }); 
    }); 
    
    除了摩卡咖啡,这些都是很好的做法,以确保您的服务器顺利启动。要在您之前完成Mocha集成(我喜欢使用承诺):


    我曾面临过完全相同的问题。我已经重新设计了我的express服务器,现在不需要等待数据库连接或任何异步初始化。这也是REST服务器的理想选择,因为即使REST环境中没有请求,也不需要连接到数据库。此外,每个调用不一定需要所有模型。在我的例子中,我会在必要时初始化数据库,几乎每个调用都会这样做。@Kamrul:你能分享一些示例代码吗?supertest知道expressjs应用程序何时可以使用吗?您如何保证在初始化http谓词时数据库已准备就绪?因为我从app.js文件导出应用程序,并要求它位于每个测试文件的顶部,但数据库呢?好吧,你必须使用类似于
    mongoose.connection.once('open',callback)
    的东西,然后添加你的路由。这意味着应用程序是真正异步初始化的。你是如何处理的?在上面的代码中,我在app.js文件中使用
    mongoose.connect(config.db)
    。在数据库准备好之前,是否阻止
    mongoose.connect
    呢?如果是,事件(‘打开’等)的目的是什么?问题是我的应用程序设置是异步的,包括当我的快速路由就绪时,因此每次尝试点击该路由时supertest都会失败,因为它启动得太快。你确实需要监听端口。您只需允许supertest即可。
    您无需监听端口即可测试应用。
    。哦,那是新的。那么它是如何工作的呢?是的,这对我来说也很有效,只需在初始化/启动服务器后添加emit,然后检查应用程序。在before函数中,对它的最好回答是调用server.js中的
    setTimeout()
    ,这是一种解决方法,可以避免在
    “started”
    事件在
    “beforeAll()之前发出的竞状态
    “正在运行并准备监视事件?这似乎是有效的,因为
    “就绪”
    事件有足够的延迟,Mocha的
    before()
    函数已经运行,正在等待
    “appStarted”