最初に、モデル内のドキュメントを削除するコードと、サーバを起動するコードを記述します。
test/helper.js
var mongoose = require('mongoose')
, app = require('../app')
, Post = require('../models/post').Post
, User = require('../models/user').User;
var serverActivity = false
, models = [Post, User];
process.on('exit', function () {
// サーバが起動していたら終了する
if (serverActivity) {
app.close();
}
});
module.exports = {
/**
* 配列modelsに入っているドキュメントを全て削除する
*/
initDB: function initDB(callback, count) {
var cnt = count || 0;
models[cnt].remove(function () {
cnt += 1;
if (cnt === models.length) {
callback();
} else {
initDB(callback, cnt);
}
});
},
/**
* サーバが起動していなかったら起動する
*/
readyServer: function (callback) {
if (serverActivity) {
process.nextTick(callback);
} else {
serverActivity = true;
app.listen(3030, function () {
process.nextTick(callback);
});
}
return;
}
};
次に、実際にテストを書いていきます。
test/controllers/posts.test.js
var assert = require('assert')
, request = require('request')
, vows = require('vows')
, zombie = require('zombie')
, helper = require('../helper')
, Post = require('../../models/post').Post;
var url = 'http://localhost:3030';
vows.describe('posts').addBatch({
'GET /': {
topic: function () {
helper.readyServer(this.callback);
},
'after readyServer': {
topic: function () {
request(url + '/', this.callback);
},
'should response 200': function (err, res, body) {
assert.equal(res.statusCode, 200);
}
}
},
'GET /posts': {
topic: function () {
helper.initDB(this.callback);
},
'after initDB': {
topic: function () {
var post = new Post({ title: 'hello world' });
post.save(this.callback);
},
'after saving post': {
topic: function (err, post) {
helper.readyServer(this.callback);
},
'after readyServer': {
topic: function () {
zombie.visit(url + '/posts', this.callback);
},
'should display the post': function (err, browser, status) {
assert.equal(browser.text('ul#posts li'), 'hello world');
}
}
}
}
}
}).export(module);
12行目から24行目までは、
という処理になっています。26行目から49行目までは、
という処理になっています。
Vowsでは、topic
という関数の中で this.callback
という関数を使うことができます。
この関数を、helper.initDB
や helper.readyServer
などのコールバック関数を引数に持つ関数に渡し、
その下にさらに topic
関数をネストして記述することで、非同期的な命令を順番に処理させることができるようです。
ただ、結構冗長なコードになっているので、もう少し簡潔に書けないかなあと思っています。 みんなはどうしているんだろう…。