2014-02-20 97 views
2

在我的控制,我有:如何单元测试依赖于承诺的AngularJS控制器?

$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的退货承诺或绕过?

回答

5

只需用嘲笑的方法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 
}); 
}); 
+0

我得到'TypeError:'undefined'不是一个对象(评估'deferred.resolve')' – Shamoon

+0

@Shamoon我做了一个更新,你使用的是完全相同的代码吗?如代码所示,确保在测试中可以访问deferred变量。 – Mik378

+0

如何使用'$ injector'设置来完成此操作?我使用http://nathanleclaire.com/blog/2013/12/13/how-to-unit-test-controllers-in-angularjs-without-setting-your-hair-on-fire/作为基准我的测试 – Shamoon

0

简短的回答:调用$scope.$index();后添加$scope.$apply();

长答案:您的问题可能是由于$ q传播承诺解决方案。事实上,解析只发生在执行$摘要时。我不知道为什么在测试过程中不执行$ digest,而是在正常使用过程中执行,但无论如何,在这里的Angular文档中建议使用此解决方案:https://docs.angularjs.org/api/ng/service/ $ q。

更重要的是,您可以直接在您的案例中使用$scope.$digest();而不是$scope.$apply();,因为$ apply只是在调用$ digest之前运行传递给它的任何函数的包装器。

相关问题