4

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 番目の実装はテスト可能ですが、スコープにデータを添付する意図した方法ではありません。

4

2 に答える 2

1

私は同じ問題を抱えていて、テストで次のようにしました:

it("leaves a 'countries' promise that resolves to countries in the scope", function() {
  var value = null;
  scope.countries.then(function(v) {
    value = v;
  });
  scope.$apply();
  expect(value).toEqual([{ Code: "SE", Name: "Sweden" }]);
});

カテゴリではなく国ですが、同じ手法があなたの場合に機能するはずです。

(スコープ変数を作成し、$httpBackend を使用して GET 期待値を設定する beforeEach を省略しましたが、もちろん必要です。)

于 2013-05-10T19:00:48.213 に答える
1

あなたが言う時

$scope.categoriesList = categoryService.search().then(function(response) {
  return response;
}

$scope.categoriesList割り当てられていませんresponse。代わりに、(テストで示されているように)に解決される新しいpromiseが割り当てられます。元の約束はすでに に解決されているため、次のようにすることができます。responseresponse

$scope.categoriesList = categoryService.search()

ドキュメントが意味することは、$scope.categoriesListこのようなプロミスに割り当てることができ、ビューは式をそれが解決される値として扱いcategoriesListます (この場合、response)-実際にはその値を取得してスコープに割り当てません.

[アップデート]

コントローラーをテストしていて、categoryService 自体をテストしていない場合は、約束を完全に除外します。おそらく次のようなものです。

it('populates the categoriesList from the categoryService', inject(function(categoryService, $controller, $rootScope) {
  var $scope = $rootScope.$new();
  var catList = [{id:1, name:"Animal"},{id:2, name:"Vegetable"}];
  spyOn(categoryService, 'search').andReturn(catList);

  $controller(myController, {'$scope': $scope});
  expect(categoryService.search).toHaveBeenCalled();

  $scope.$digest();

  expect($scope.categoriesList).toEqual(catList);
}));
于 2013-01-16T05:58:04.973 に答える