mocha+chai+sinsonでテストを書く為に必要な最低限の知識
まとめ
- Mochaではrspecっぽい感じにテストが書ける
- ただし、done()を呼ぶ必要がある等、細かい部分に差異がある
- sinonにはいろいろ便利機能がある
Mochaの使い方
coffeescriptを前提にしています。
テストの書き方
Mochaのテストは以下のように、itにテスト内容を書いた関数を渡し、
そのitを呼び出す関数をdescribeに渡すしようです。
describe "test root", ->
it "name", (done) ->
assert.equal getUserName, "user"
done()
ただし、it関数では必ずdone()を呼び出す必要があります。
これを呼ばない場合は終了を待ち続け、
一定時間後にタイムアウトしてテストが失敗した扱いになります。
beforeの使い方
rspecのbeforeにあたるものは、beforeEachになります。
なお、変数を他のブロックに渡したい場合、
以下のようにdescribeの中に変数名を書いておいて、
beforeEachのなかで設定する必要があるみたいです。
参考
describe "test", ->
room_name = undefined
beforeEach (done) ->
room_name = "test_room"
done()
describe "functions", ->
it "executeNoteShow", (done) ->
assert.equal getRoomName(room_name), room_name
done()
pendingテストの作り方
テストの用意はしたけど、とりあえずpendingにしておきたい場合は二通りの方法があります。
describe "functions", ->
it "pending test" // 関数を渡さない場合
// it.skipの場合、引数を渡しても実行されずにスキップする
it.skip "pending test 2", ->
done()
外部ファイル読み込み
test.coffeeで
class Test
なんかいろいろ
module.exports.Test = Test
と、クラスを宣言し、module.exportsに代入します。 その後、使いたいファイル側で
Test = require('../src/test.coffee').Test
と書くと、以降Testでそのクラスが呼び出せます。
#chaiの使い方
assertを使う
前述のテストではassertを使っていますが、Mochaにはassertは入っていないため、
別ライブラリのchaiを読み込む必要があります。
global.assert = require("chai").assert
これで、 assert.equalや assert.notEqualが使えます。
sinonの使い方
mockやstubを使う
Mochaにはmockやstubの為の物は含まれていないので、
今度はsinonを読み込む必要があります。
global.sinon = require('simon')
使い方は以下の通りです
// robot.brainがstubになる
robot = new Object()
robot.brain = sinon.stub()
// hubot_note.executeNoteShowを置き換え、
// hubot_note.executeMessage実行時に、
// "test", null, nullの引数で一回だけ実行されたかをチェックする
spy = sinon.spy(hubot_note, "executeNoteShow")
spy.withArgs("test", null, null)
response = hubot_note.executeMessage(room_name, "hubot note show")
assert.ok spy.withArgs("test", null, null).calledOnce
時間変更の仕方
new Date()
などによって日付がちゃんと設定されたかどうかを確認したい場合、
グローバルなDate()部分を置き換える必要があります。
…というのはよくあることなので、sinon側で既に用意されています。
@clock = sinon.useFakeTimers(0,
"setTimeout", "clearTimeout",
"setInterval", "clearInterval", "Date")`
これで、以降のDateコマンドは第一引数で指定した0(1970年1月1日0時0分0秒)を必ず返すようになるため、
この時間かどうかをチェックすれば大丈夫です。
また、以下のように戻り値のオブジェクトのtickメソッドにより、
指定したミリ秒だけ時間を進めることもできます。
@clock.tick(3600000)
sinonのその他の機能
sinonに関しては他にもいろいろ有用なものがあります。
ちょっと古いですが、以下のmixiさんのブログ記事は参考になると思います。