如何对依赖于承诺的AngularJS控制器进行单元测试?

时间:2014-02-20 00:32:42

标签: javascript angularjs unit-testing promise

在我的控制器中,我有:

  $scope.index = function() {
    CompanyService.initialized.then(function() {
      var company_id = CompanyService.getCompany()._id;
      LocationService.list(company_id, $routeParams.location_parent_id).then(function(response) {
        if(response.data.status === 'ok') {
          $scope.locations = response.data.locations;
          $scope.current_location = response.data.location || null;
        }
      });
    });
  }

所以它应该得到LocationService列表并且测试如下:

it('should get locations', function() {
  $httpBackend.when('GET', '/api/v1/location/list').respond({status: 'ok', locations: ['loc1', 'loc2']})
  $scope.index();
  expect($scope.locations.length).toEqual(2);

然而,这种情况从未发生过,因为CompanyService具有在单元测试中永远无法解决的承诺。我如何模拟返回的CompanyService承诺或绕过它?

2 个答案:

答案 0 :(得分:5)

只需使用Jasmine中的createSpyObj方法模拟调用:

describe('one test', function(){

 var deferred, CompanyService, $scope;

 beforeEach(inject(function ($q, $rootScope, $controller) {
  params = {
        $scope: $rootScope.$new(),
        CompanyService = jasmine.createSpyObj('CompanyService', ['initialized'])
  }
  params.CompanyService.initialized.andCallFake(function () {
      deferred = $q.defer();
      return deferred.promise;  //will fake to return a promise, in order to reach it inside the test
    });
  $controller('YourController', params);
 });

 it('my test', function(){
     deferred.resolve({}); //empty object returned for the sample but you can set what you need to be returned
     $scope.$digest(); //important in order to resolve the promise
    //at this time, the promise is resolved! so your logic to test can be placed here
 });
});

答案 1 :(得分:0)

简短回答:致电$scope.$apply();后添加$scope.$index();

答案很长:你的问题可能是因为$ q宣传了promises解决方案。实际上,解析仅在执行$ digest时发生。我不知道为什么在测试期间没有执行$ digest,而是在常规使用期间,但是在Angular文档中建议使用此解决方案:https://docs.angularjs.org/api/ng/service/ $ q。

你可以在你的情况下直接使用$scope.$digest();而不是$scope.$apply();,因为$ apply只是在调用$ digest之前运行传递给它的任何函数的包装器。