概要
弊社では一部の社内プロジェクトでSails.jsを利用しています。その中で得られたベストプラクティスやらバッドプラクティスをまとめていこうと思います。
第3回はテストについて。
動作環境
node.js v0.12.7
Sails.js v0.11.2
sails-mysql v0.11.0
テスト対象
今回はService層(Services -> Modelまで)のテストを行います。O/R MapperのWaterlineを通してDBアクセスまで正常に動作することを確認します。
テストの構成
ディレクトリ構成
test
|
|_fixture : テスト用データの定義
|_services: (servicesの)テストコード
|_utils: テストコードで使うユーティリティモジュール
|_bootstrap.spec.js: テストの事前準備用モジュール
Sailsの起動処理
/test/bootstrap.spec.js
にてテストの事前準備としてSailsの起動を行っています。/app.js
にある通り、Sails.lift()
を実行することでSailsを起動することが出来ます。
var Sails = require('sails');
before(function (done) {
Sails.lift({
log: {
level: 'silent'
}
}, function (err, sails) {
if (err) return done(err);
done();
});
});
Fixtureの活用
実際のDBにつないでテストを行うため、Fixtureを使って初期データを注入しています。barrelsというSails.js用のFixtrueがあるので、これを使用します。今回はサンプルとしてLocalDBを使用するため、初期化処理(.tmp/localDiskDB.db
の削除)をしています。MySQLを使用している場合はchild_process
を使用してDDLを流すと良いでしょう。
var exec = require('child_process').exec;
var Barrels = require('barrels');
var fs = require('fs');
var FixtureFactory = {
// データベースの初期化
resetDatabase: function (){
return new Promise(function(resolve, reject){
fs.unlink('.tmp/localDiskDb.db', function(error) {
if (error) return reject(error);
resolve();
});
});
},
generateDataFromFixture: function(){
var self = this;
return new Promise(function(resolve, reject){
self.resetDatabase().then(function(){
var barrels = new Barrels();
barrels.populate(['room'], function(err) {
if(err) return reject(err);
barrels.populate(['message'], function(err) {
if (err) return reject(err);
resolve();
}, false);
}, false);
}).catch(function(err){
sails.log.error(err);
reject(err);
});
});
}
};
module.exports = FixtureFactory;
テストコード
Servicesモジュールをrequire()
し、メソッドコールの結果を確認します。弊社ではテスティングフレームワークにmocha
、アサーションはpower-assert
を使用しています。
var assert = require('power-assert');
var FixtureFactory = require('../utils/FixtureFactory');
describe('RoomService', function() {
var RoomService = require('../../api/services/RoomService.js');
before(function(done) {
FixtureFactory.generateDataFromFixture().then(function(){
done();
}).catch(function(err){
done(err);
});
});
context('find', function() {
it('should return rooms', function(done) {
RoomService.findAll().then(function(rooms) {
assert(rooms.length !== 0);
}).then(done, done);
});
});
});
レポジトリ
上記の構成は、以下のレポジトリにまとめてあります(社内勉強会で使用した資料です)。
https://github.com/KeitaMoromizato/js-study-sailsjs-test