使用mocha设置/拆除express.js应用程序

时间:2012-06-10 02:29:10

标签: node.js makefile express zombie.js

我正在尝试使用mocha创建一个独立的测试套件,在完美的世界中会启动我的express.js应用程序,使用zombie渲染页面,检查一堆东西,然后拆除/杀死快递。 js申请。

有一种简单/最好的方法吗?

NB。我可以在运行测试之前运行快速应用程序服务器,但如果你不打算剃掉它们,那么Yaks有什么用呢。

2 个答案:

答案 0 :(得分:28)

首先,您需要将实际应用设置移动到模块中,然后将其导入实际启动应用的文件中。现在这是分开的,您可以在实际收听之前让应用程序处于完整状态。

您应该将应用程序的实际设置移动到一个单独的文件中,让我们称之为app.js,可以从您运行节点的文件中调用listen,让我们称之为index.js。

所以,app.js看起来像:

    var express = require('express')
  , routes = require('./routes');

var app = module.exports = express.createServer();

// Configuration

app.configure(function(){
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));
});

app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});

app.configure('production', function(){
  app.use(express.errorHandler());
});

// Routes

app.get('/', routes.index);

和index.js看起来像:

var app = require('./app');

app.listen(3000, function(){
  console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
});

这样就可以分开加载您的应用,让您将应用加载到单元测试中。

在您的单元测试中,您可以使用设置方法和拆解方法来启动和关闭服务器。

在文件test / app_tests.js中:

describe('app', function(){
  var app = require('../app');
  beforeEach(function(){
    app.listen(3000);
  });
  // tests here
  afterEach(function(){
    app.close();
  })
});

答案 1 :(得分:4)

除了Oved D回答。

在express-app.js或其他文件中描述您的应用:

module.exports = function (o) {
  o = o || {};
  var app = express();

  // app.configure
  // configure routes
  if (o.someOption) {
    // some additional test code
  }

  return app;
}

描述test / 01-some.js中的测试:

var expressApp = require('../express-app');
describe('some', function () {

  // just describe needed vars
  var app, server, port;

  // describe setup
  before(function (next) {
    // create app when 
    app = expressApp({routes: /api\/some\/.*/ /* put here some test options ...*/});
    // creating listener with random port
    server = app.listen(function () {
      // store port when it ready
      port = server.address().port;
      // and go to tests
      next();
    });
  });

  // tests
  it('should return valid result', function (done) {
    // do a simple request to /api/some
    http.request({
      host: 'localhost',
      port: port,
      path: '/api/some'
    }, function (res) {
      if (res.err) throw new Error(res.err);
      done();
    });
  });

  // teardown
  after(function () {
    // stop listening that port
    server.close();
  });

});

完成。 ; - )

现在你可以创建任何类似的测试。建议您通过将params传递给express-app.js模块,在测试中仅启用所需的URL和服务。


更新

不确定它在mocha中是如何运作的,但最好将beforeafter来电转移到init.js,然后将其加载mocha --require init.js

文件看起来应该是这样的:

// use it in your mocha tests
global.setupEnv = function setupEnv (o, before, after) {

    // just describe needed vars
    var env = Object.create(null);

    // setup
    before(function (next) {
        // create app
        env.app = expressApp(o);
        // creating listener with random port
        env.server = env.app.listen(function () {
            // store port when it ready
            port = env.server.address().port;
            env.app.log('Listening on ', env.port);
            // and go to tests
            next();
        });
    });

    // teardown
    after(function () {
        // stop listening that port
        env.server.close();
    });

    return env;
}

在你的测试中:

// requiring dependencies
var request = require('request');

describe('api', function () {

    // describe setup
    var env = global.setupEnv({
            routes: 'api/some'
        }, before, after);

    // tests
    it('should pass', function (done) {
        request('http://localhost:' + env.port, function (error, response, body) {
            done();
        });
    });

});