Установка/отключение приложения express.js с помощью мокко

Я пытаюсь создать автономный набор тестов с использованием mocha, который в идеальном мире запустит мое приложение express.js, применит зомби, чтобы отобразить страницу, проверить кучу вещей, а затем отключить/убить экспресс. js.

Есть ли простой/лучший способ сделать это?

NB. Я могу просто запустить экспресс-сервер приложений до запуска тестов, но что хорошего - Якс, если вы не собираетесь их бреять.

Ответы

Ответ 1

Во-первых, вам нужно переместить фактическое приложение в модуль и импортировать его в файл, который фактически запускает ваше приложение. Теперь, когда это отдельно, вы можете иметь приложение в полном состоянии, прежде чем слушать.

Вы должны перенести фактическую настройку своего приложения в отдельный файл, позвонив ему в app.js, можете вызвать прослушивание из файла, с которого вы запускаете node, позвоните ему 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);
});

Это отвлекает загрузку вашего приложения от фактического прослушивания, позволяя вам загружать это приложение в свои модульные тесты.

В ваших модульных тестах вы сделаете что-то в методе установки и методе teardown, чтобы вызвать и снести сервер.

В файле test/app_tests.js:

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

Ответ 2

В дополнение к ответу 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;
}

описывают тесты в тесте /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();
  });

});

Готово.; -)

Теперь вы можете создать любое количество таких тестов. Порекомендуйте вам включить только необходимые URL-адреса и службы в тестах с их определением путем передачи параметров в модуль express-app.js.


Update:

Не знаете, как это работает в mocha, но лучше перемещать вызовы before и after на 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();
        });
    });

});