我正在使用 PhoneGap 和 Knockout.js 构建一个移动应用程序,并且我正在使用 QUnit 对其进行单元测试。我遇到了一个小问题。
它本质上是一个照片库,作为其中一项测试的一部分,我想首先获取所有通过 AJAX 加载的相册。然后我想返回第一张相册中的所有照片。
我可以单独获取相册,并对该功能进行工作单元测试,但我在扩展它以获取照片时遇到了很多困难。
我的视图模型称为 AlbumViewModel,它有两个可观察的数组,称为专辑()和照片()。首次打开应用程序时,会通过 AJAX 自动获取相册,并用结果填充相册()。当一个相册被选中时,它被传递给 getPhotos(),它使相册() 无效并获取相册中的照片,将它们存储在 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() 可观察数组。
这绝对没问题。但是,获取照片的测试存在更多问题。我基本上需要首先获取相册,然后,一旦它们被获取,获取其中一张并获取照片。现在,正如您在上面看到的,我通过订阅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 响应。
我以为我可以订阅相册()一个订阅中的照片()可观察数组,但不幸的是,Chrome的开发人员工具返回以下错误:
Uncaught RangeError: Maximum call stack size exceeded
这似乎暗示了一个无限循环,可能意味着嵌套订阅可能不是最好的方法。谁能指出我误入歧途的地方?因为这是我第一次同时使用 QUnit 和 Knockout.js,所以我感觉有点超出我的深度。
TL;DR:我正在使用 QUnit 对 Knockout.js 应用程序进行单元测试。需要等待一种方法通过 AJAX 工作,然后获取返回的数据并将其传递给同样通过 AJAX 工作的第二种方法,以便测试代码。订阅第一种方法仅用于测试,但不能在第一个订阅中嵌套第二个订阅。关于我如何做到这一点的任何建议?