2014-02-15 mochaで重複コードの排除をためした
mochaで重複コードの排除をためした。
bouzuya/node-backlog-apiのpromiseパターンを適用しようとしているのだけれど、それにともなってテストコードを見直している。
node-backlog-apiのテストコードは相当にひどい。いろいろとひどい点はあるのだけれど、重複コードがひどい。例えば、expect
の準備だったり、テストサーバーを立ち上げるコードが各ファイルに記述してあって、見事なまでに重複している。もちろん、API呼び出しのハンドラーは違うのだけど、明らかな重複だ。これは相当にひどい。
そこで重複コードの排除を考えた。
今回からexpect.js
をchai
のbdd style(expect)に置き換えようと考えているので、次のような記述が必要になる。
var expect = require('chai').use(require('chai-sinon')).expect;
そして、先に書いたようなテストサーバーを立ち上げるbeforeEach
も必要である。
これらを簡潔にセットアップしてくれる記述がしたい。Ruby on Railsほかの例にならってhelper
を準備することにした。
test/helper.js
を用意し、各ファイルからは次の1行を書くだけでOKという状態にする。
require('./helper');
例えばtest/helper.js
の内容は次のようになる。
global.expect = require('chai').use(require('sinon-chai')).expect;
var xmlrpc = require('xmlrpc');
var backlog = require('../');
beforeEach(function(done) {
global.server = xmlrpc.createServer({
host: 'localhost',
port: 3000
}, function() {
global.client = backlog();
client._client = function() {
return xmlrpc.createClient({
url: 'http://localhost:3000/XML-RPC'
});
};
done();
});
});
afterEach(function(done) {
global.server.close(done);
});
globalにexpect
,server
,client
を設定している。expectはともかく、ほかは本来設定しなくても良いのだけれど、既存コードがserver
という変数名ですべて使っていて、それを置換しても見にくいので、このようにした。プロダクトコードではダメだけどね。
mochaはroot hookというのが可能で、describe
の中だけでなくrootでbeforeEach
などを設定できる。これはすべてのテストに対して動く。
最初の構想ではrequire('./helper');
も重複なので排除したかった。mochaには--require
というオプションが準備されていて、テスト実行前に共通でrequire
してくれるのだけれど、--require
で指定されたファイル中ではbeforeEach
は設定することができないため、今回はこのような記述になっている。
この重複の排除のおかげで、テストコードの見た目はかなり良くなった。
またsinon.jsを使う(require('chai-sinon')
)ことでテストダブルの扱いもかなり良くなっている。今週はmochaでのテスト力が上がっているように感じる。明日はこの修正をおえて、node-backlog-apiの新バージョンをリリースしたい。