PhoneGapとKnockout.jsを使用してモバイルアプリを構築しており、ユニットテストにQUnitを使用しています。私は小さな問題に遭遇しました。
これは本質的にフォトギャラリーであり、テストの1つの一環として、最初にAJAXを介してロードされるすべてのアルバムを取得したいと思います。次に、最初のアルバムのすべての写真を返したいと思います。
アルバムだけを入手して、その機能の単体テストを行うことはできますが、写真を取得するためにアルバムを拡張するのは非常に困難です。
私のビューモデルはAlbumViewModelと呼ばれ、albums()とphotos()という2つの監視可能な配列があります。アプリケーションが最初に開かれると、アルバムはAJAXを介して自動的にフェッチされ、albums()に結果が入力されます。アルバムが選択されると、getPhotos()に渡されます。getPhotos()はalbums()を無効にし、アルバム内の写真をフェッチして、photos()に保存します。
アルバムの単体テストは次のとおりです。
test("Check albums created", function () {
'use strict';
// Stop the test
stop();
// Declare variables used
var avmodel;
// Create AlbumViewModel
avmodel = new AlbumViewModel();
// Wait for album fetch
avmodel.albums.subscribe(function () {
// Check albums length is more than 0
ok(avmodel.albums().length > 0, "Albums length is " + avmodel.albums().length);
// Run the tests for the albums
start();
});
});
これはAJAXを介してサーバーからデータをフェッチするため、albums()の監視可能な配列が設定されるまで実行を遅らせる必要がありました。
これは完全に正常に機能します。ただし、写真を取得するためのテストはより問題があります。基本的に、最初にアルバムをフェッチする必要があります。次に、アルバムがフェッチされたら、そのうちの1つを取得して写真をフェッチします。さて、上記のように、albums.subscribeイベントにサブスクライブし、完了したらテストを実行するだけで、アルバムを使用してこれを達成しました。だから、それはphotos()をテストするための方法のように見えました。
写真をテストするために私が書いたものは次のとおりです。
test("Check photos created", function () {
'use strict';
// Stop the test
stop();
// Declare variables used
avmodel;
// Create AlbumViewModel
avmodel = new AlbumViewModel();
// Wait for album fetch
avmodel.albums.subscribe(function () {
// Only check the first time it runs
var albumToGet;
if(typeof albumToGet === "undefined") {
// Get the album to examine
if (avmodel.albums()) {
albumToGet = avmodel.albums()[0];
// Subscribe to the photos observableArray
avmodel.photos.subscribe(function () {
var photos = avmodel.photos(albumToGet);
// Check photos length more than 0
ok(photos.length > 0, "Photos length is " + photos);
// Restart
start();
});
// Get the photos for this album
avmodel.getPhotos(albumToGet);
}
}
});
});
基本的に、最初にAJAX応答が受信されて処理されるまでアルバムの詳細の取得を遅らせる必要があります。次に、それが完了したら、albumToGetオブジェクトを最初のアルバムに設定してgetPhotosに渡します。次に、写真をフェッチするためのAJAX応答が受信されて処理されるまで、テストの実行を遅らせます。
albums()のサブスクリプション内のphotos()observable配列をサブスクライブできると思いましたが、残念ながらChromeの開発者ツールは次のエラーを返します。
Uncaught RangeError: Maximum call stack size exceeded
これは無限ループを示唆しているように思われます。つまり、サブスクリプションのネストは最善のアプローチではない可能性があります。誰かが私が迷ったところを指摘できますか?QUnitとKnockout.jsの両方を使用するのはこれが初めてなので、少し深みがあります。
TL; DR:QUnitを使用してKnockout.jsアプリケーションの単体テストを行っています。コードをテストするために、1つのメソッドがAJAXを介して機能するのを待ってから、返されたデータを取得し、それをAJAXを介して機能する2番目のメソッドに渡す必要があります。最初のメソッドへのサブスクライブは、それをテストするためだけに機能しましたが、最初のメソッド内に2番目のサブスクリプションをネストすることはできません。私がこれをどのように行うことができるかについての提案はありますか?