JS学習のJavaScript非同期方法のユニットテスト
背景の説明
最近は仕事上の理由で、JavaScriptテストフレームワークJasmineを研究しました.他のユニットのテストフレーム(例えばJUnitなど)と同様に、編纂ユニットのテストは複雑ではなく、テスト対象の入出力を明らかにするのが難しいので、ここでは説明しきれません.テストの用例を作成する過程で、いくつかのJavaScript方法は比較的に時間がかかるので、非同期方式を採用しましたが、私達が普段使っているコールバック関数とは違って、システムメッセージを送る方式で通知します.システムには多くのメッセージコードが定義されています.メッセージコードを通じてJavaScript方法の実行結果が分かります.実際の作業環境では、ブラウザがカスタマイズされているので、この解決方法を一般ブラウザでデモンストレーションできるように、実際のコードの代わりにwindow.postMessageを使って説明します.
この方法を見ると、まず思いつくのは、イベント傍受を登録し、非同期方法の後にある時間間隔を待って、受信したメッセージを判断することである.
ソリューション
このような仕組みがあって、async_に対してコールのテストケースは書きやすいです.コードは以下の通りです.
締め括りをつける
Jasmineはjavascript同期と非同期方法テストに対して良好なサポートを提供しており、JSユニットのテストケースを作成することができます.第三者のjsライブラリを使って、DOMイベントをテストしたり、テスト結果をファイルに保存したりすることもできます.これは次回の分析を待っています.
上記のコードの例は私のギthubプロジェクトのjsdemoにあります.
参考文献
1.Jasmine公式文書2.Using Jasmine 2.0’s New done()Function to Test Aynchronous Process
最近は仕事上の理由で、JavaScriptテストフレームワークJasmineを研究しました.他のユニットのテストフレーム(例えばJUnitなど)と同様に、編纂ユニットのテストは複雑ではなく、テスト対象の入出力を明らかにするのが難しいので、ここでは説明しきれません.テストの用例を作成する過程で、いくつかのJavaScript方法は比較的に時間がかかるので、非同期方式を採用しましたが、私達が普段使っているコールバック関数とは違って、システムメッセージを送る方式で通知します.システムには多くのメッセージコードが定義されています.メッセージコードを通じてJavaScript方法の実行結果が分かります.実際の作業環境では、ブラウザがカスタマイズされているので、この解決方法を一般ブラウザでデモンストレーションできるように、実際のコードの代わりにwindow.postMessageを使って説明します.
function async_call(data) {
window.postMessage(data, '*');
}
解決プロセスこの方法を見ると、まず思いつくのは、イベント傍受を登録し、非同期方法の後にある時間間隔を待って、受信したメッセージを判断することである.
describe("WrongAsyncTest", function() {
var code;
var foo = {
onmessage: function(e) {
code = e.data;
}
};
beforeEach(function() {
window.addEventListener('message', function(e) {
foo.onmessage(e);
}, false);
jasmine.clock().install();
});
afterEach(function() {
jasmine.clock().uninstall();
});
it('testAsyncCall', function() {
async_call('10001');
jasmine.clock().tick(1000);
expect(code).toEqual('10001');
});
});
実際にはこれは通用しません.asyncにいますが.callの後に十分な時間が待っていますが、javascriptコードは実際にシングルスレッドで実行されていることを知りたいです.だからtestAyncCallの方法でどれぐらい待てばいいですか?foo.onmessageはtestAryncCallの実行後に呼び出されるので、expect(code).toEqual(‘10001’)という断言の中で、codeの値はまだ定義されていません.得られた結果は:Expected undefined to equal '10001'.
この道は通じません.jasmineの文書を見て、その中の一部はAynchronous Supportです.jasmineのbeforeAll、afterAll、beforeEach、afterEach、it呼出しの中で、オプションのパラメータを追加できます.非同期方法の実行が完了したら、このコールバック関数を呼び出して、次のテスト方法をjasmineに通知します.最初は何を言っているのか分からないようですが、例を挙げて説明します.describe("Synschronous specs", function() {
var value;
beforeEach(function(done) {
setTimeOut(function() {
value = 0;
done();
}, 1);
});
it("first", function() {
expect(value).toEqual(0);
});
この例では、BeforeEachは、Jasmineがdoneコール関数で呼び出される前に次のテスト方法を実行しないことを示すdoneパラメータを追加しています.だから、firstテストはbeforeEachのタイマーのタイムアウトを待ち続け、done()を実行してから実行されます.ソリューション
このような仕組みがあって、async_に対してコールのテストケースは書きやすいです.コードは以下の通りです.
describe("AsyncTest", function() {
var code;
var foo = {
setcode: function(e) {
code = e.data;
},
onmessage: function(e) {
console.log("onmessage");
}
}
window.addEventListener('message', function(e) {
foo.onmessage(e);
}, false);
beforeEach(function(done) {
spyOn(foo, "onmessage").and.callFake(function(e) {
foo.setcode(e);
done();
});
async_call('10001');
});
it('testAsyncCall', function() {
expect(foo.onmessage).toHaveBeenCalled();
expect(code).toEqual('10001');
});
});
説明では、doneはbefore All、afterAll、beforeEach、afterEach、it呼び出しのオプションパラメータですので、foo.onmessageでは呼び出しできません.そこで、コードに迂回の方式が採用されています.spyOnを通じて関数が呼び出されているかどうかを監視します.and.callFakeとは、モニタされた関数が呼び出されたときに、モニタされた関数を提供された関数で置換するという意味です.上のコードについて言えば、foo.onmessageが呼び出されたときに使います. function(e) {
foo.setcode(e);
done();
}
この呼び出しの代わりに.なぜfoo.setcodeメソッドを追加したのかというと、Jasmineドキュメントを見ても、監視関数によって呼び出された関数が見つからないので、関数を実行する方法が追加されます.締め括りをつける
Jasmineはjavascript同期と非同期方法テストに対して良好なサポートを提供しており、JSユニットのテストケースを作成することができます.第三者のjsライブラリを使って、DOMイベントをテストしたり、テスト結果をファイルに保存したりすることもできます.これは次回の分析を待っています.
上記のコードの例は私のギthubプロジェクトのjsdemoにあります.
参考文献
1.Jasmine公式文書2.Using Jasmine 2.0’s New done()Function to Test Aynchronous Process