JasmineでSammy.jsアプリをテストする
RSpecライクなJavascript用BDDフレームワークJasmineで、SinatraライクなWebフレームワークSammy.jsで作られたアプリをテストしてみる。
非同期処理を伴わない場合
Sammy.js app
var app = $.sammy(function() { this.get('#/', function() { $('h1').html("hoge"); }); };
ルートの実行が終了すると、event-context-afterトリガーが起こる。
この発生を検知してからテストを行えばOK。
Jasmine
describe('testing sammy.js app', function() { beforeEach(function() { $('body').append('<div id="jasmine"><h1>Replace me</h1></div>'); app.executed = false; app.bind('event-context-after', function() { app.executed = true; }); }); afterEach(function() { $('div#jasmine').empty().remove(); }); it('should set h1', function() { app.run('#/'); waitsFor(function() { return app.executed; }, "app doesn't stop", 10000); runs(function() { expect($('h1').html()).toEqual('hoge'); }); });
非同期処理を伴う場合
Sammy.js app
var app = $.sammy(function() { this.get('#/async', function() { // 非同期処理 this.load('/public/data/myfile.txt') .then(function(content) { $('h1').text(content); }); }); });
ルート内で非同期処理を行うと、非同期処理の終了を待たずしてevent-context-afterトリガーが起こってしまう。
なので独自にルートの実行が終了したことを通知するイベントトリガーを作る必要がある。
var app = $.sammy(function() { this.get('#/async', function() { this.load('/public/data/myfile.txt') .then(function(content) { $('h1').text(content); // ルートの実行が終了したことを知らせる this.trigger('executed'); }); }); });
Jasmine
describe('testing sammy.js app', function() { beforeEach(function() { $('body').append('<div id="jasmine"><h1>Replace me</h1></div>'); app.executed = false; app.bind('executed', function() { app.executed = true; }); }); afterEach(function() { $('div#jasmine').empty().remove(); }); it('should be h1 text equals to public/data/myfile.txt', function() { app.run('#/async'); waitsFor(function() { return app.executed; }, "app doesn't stop", 10000); runs(function() { expect($('h1').html()).toEqual(myfile-data); }); }); });