18

モカを使用してスタンドアロンのテスト スイートを作成しようとしています。完璧な世界では、express.js アプリケーションを起動し、ゾンビを使用してページをレンダリングし、一連のものをチェックしてから、express.js アプリケーションを破棄/強制終了します。

これを行う簡単/最良の方法はありますか?

注意。テストを実行する前に高速アプリケーション サーバーを実行することもできますが、Yak を削らないのであれば、Yak は何の役にも立たないでしょう。

4

2 に答える 2

29

まず、実際のアプリの設定をモジュールに移動し、それを実際にアプリを起動するファイルにインポートする必要があります。これが分離されたので、実際に聞く前にアプリを完全な状態にすることができます。

アプリの実際の設定を別のファイルに移動する必要があります。それを 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();
  })
});
于 2012-07-17T23:07:12.390 に答える
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();
  });

});

終わり。;-)

これで、そのようなテストをいくつでも作成できます。Express-app.js モジュールに params を渡して定義し、テストで必要な URL とサービスのみを有効にすることをお勧めします。


アップデート:

それがどのように機能するかはわかりません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();
        });
    });

});
于 2014-07-01T15:22:36.447 に答える