我正在尝试使用 mocha 创建一个独立的测试套件,在一个完美的世界中,它将启动我的 express.js 应用程序,使用僵尸来呈现页面,检查一堆东西,然后拆除/杀死 express.js 应用程序。
有没有简单/最好的方法来做到这一点?
注意。我可以在运行测试之前运行 express 应用程序服务器,但是如果你不打算刮牦牛,那么 Yaks 有什么用。
首先,您需要将您的实际应用程序设置移动到一个模块中,并将其导入实际启动您的应用程序的文件中。现在这是分开的,您可以在实际收听之前让应用程序处于完整状态。
您应该将应用程序的实际设置移动到一个单独的文件中,我们称之为 app.js,可以从运行节点的文件中调用监听,我们称之为 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);
});
这将加载您的应用程序与实际监听它分开,允许您将该应用程序加载到您的单元测试中。
在你的单元测试中,你会在 setup 方法和 teardown 方法中做一些事情来启动和关闭服务器。
在文件 test/app_tests.js 中:
describe('app', function(){
var app = require('../app');
beforeEach(function(){
app.listen(3000);
});
// tests here
afterEach(function(){
app.close();
})
});
除了 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 模块来定义测试中仅需要的 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();
});
});
});