angular.js ソースによると:
$q プロミスは、Angular のテンプレート エンジンによって認識されます。つまり、テンプレートでは、スコープにアタッチされたプロミスを結果の値であるかのように扱うことができます。
バックエンドからカテゴリのリストを取得するコントローラーがあります。
function myController($scope, $categoryService) {
...
$scope.categoriesList = categoryService.search().then(function(response) {
return response;
}
...
}
そして私のテンプレートには選択があります:
<select multiple ng-model="categories" ng-options="category.name for category in categoriesList"></select>
これはブラウザで「機能」します(選択すると、入力されたリストが表示されます)
しかし、これをどのようにテストしますか?
私は次の仕様を持っています:
it('populates the categoriesList from the categoryService', inject(function(categoryService, $q, $controller, $rootScope) {
var $scope = $rootScope.$new();
var catList = [{id:1, name:"Animal"},{id:2, name:"Vegetable"}];
var deferred = $q.defer()
spyOn(categoryService, 'search').andReturn(deferred.promise);
$controller(myController, {'$scope': $scope});
expect(categoryService.search).toHaveBeenCalled(); // PASSES
deferred.resolve(catList);
$scope.$digest();
expect($scope.categoriesList).toEqual(catList); // FAILS, returns the promise instead
}));
イニシャライザをそのように書き直した場合
...then(function(response) {
$scope.categoriesList = response;
}
私のテストはパスしますが、その場合、promise をスコープに割り当てておらず、テンプレート エンジンが promise を解決していません。最初の実装はフレームワークが意図しているもののようですが、テストできません。2 番目の実装はテスト可能ですが、スコープにデータを添付する意図した方法ではありません。