According to angular.js source:
$ q promises are recognized by the template engine in angular, which means that in templates you can treat promises attached to the scope as if they were the resulting values.
So, I have a controller that gets a list of categories from the backend,
function myController($scope, $categoryService) { ... $scope.categoriesList = categoryService.search().then(function(response) { return response; } ... }
and in my template I have a choice:
<select multiple ng-model="categories" ng-options="category.name for category in categoriesList"></select>
which "works" in the browser (selection shows a populated list)
but how do you test it?
I have the following specification:
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();
If I rewrote my initializer like this
...then(function(response) { $scope.categoriesList = response; }
My tests will pass, but then I will not assign a promise to the field, and the template engine does not solve the promise for me. It seems to me that the first implementation is what the framework provides, but this cannot be verified. The second implementation may be a validation, but not the intended way of attaching data to a region.