10) JasmineによるPromiseオブジェクトのテスト
JavaScriptのテスト用フレームワークであるjasmineを使ったテストの例を紹介します。jasmineでは2.0で非同期処理のテストがサポートされました。
Asynchronous Support
http://jasmine.github.io/2.0/introduction.html#section-Asynchronous_Support
テスト用のコード
テスト用の簡単なサンプルコードを定義します。
// 1秒後にfulfilledになる
function task(){
return new Promise(function(resolve,reject){
setTimeout(resolve('success'), 1000);
});
}
// 最初の状態は"init"
var result = 'init';
function func(){
return task()
.then(function(value){
// fulfilledの時、result="success"になる
result = value;
})
;
}
それではfunc()
を実行してresult==="success"
になる事を検証してみましょう。
シンプルなテスト
describe('Testing Promise', function() {
beforeEach(function(done){
func().then(function(){ done(); });
});
it('Run test after resolved', function(){
expect(result).toBe('success');
});
});
beforeEach()
のコールバック関数に引数done
を宣言すると、done()
がコールされるまで関数の終了を待機します。(この動作はit
でも同様です)
beforeEach(function(done){
func().then(function(){ done(); });
});
beforeEach()
が終了した後でit
が実行されるため fulfilled な値を検証する事ができます。
it('Run test after resolved', function(){
expect(result).toBe('success');
});
時間のかかるテスト
task()
を編集して6秒後に fulfilled になるようにしてみましょう。
function task(){
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve('success');
}, 6000);
});
}
今度はテストが失敗します。 エラーメッセージにはタイムアウトと記載されています。
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
jasmineの非同期処理のタイムアウトは5秒です。
エラーメッセージに記載されているjasmine.DEFAULT_TIMEOUT_INTERVAL
を変更する事で延ばす事ができます。
describe("Testing Promise", function() {
var originalTimeout;
beforeEach(function() {
originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
// 10秒まで延ばす
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
});
it("Run test after resolved", function(done) {
func()
.then(function(){
expect(result).toBe('success');
done();
})
;
});
afterEach(function() {
// テストが終わったら元に戻す
jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
});
});
今度は6秒後にテストが成功するはずです。
いかがでしょうか。
done()
を呼ぶタイミングは自身の書いたコードによるため、常に Thenable な関数を書くように気をつけておくとテストが書きやすそうですね。