2013-10-24 48 views
21

我正在使用AngularJS的v1.2.0-rc.3与Jasmine测试框架。如何用Jasmine测试一个AngularJS控制器,该控制器调用返回承诺的服务方法

我想断言控制器调用服务方法。服务方法返回一个承诺。控制器看起来像这样:

angular.module('test', []) 
.controller('ctrl', ['$scope', 'svc', function ($scope, svc) { 
    $scope.data = []; 
    svc.query() 
    .then(function (data) { 
    $scope.data = data; 
    }); 
}]); 

我想测试,当服务方法的延期解析时,数据分配给范围。我创建了一个模拟的服务和单元测试是这样的:

describe('ctrl', function() { 
    var ctrl, scope, svc, def, data = [{name: 'test'}]; 
    beforeEach(module('test')); 
    beforeEach(inject(function($controller, $rootScope, $q) { 
    svc = { 
     query: function() { 
     def = $q.defer(); 
     return def.promise; 
     } 
    }; 
    scope = $rootScope.$new(); 
    controller = $controller('ctrl', { 
     $scope: scope, 
     svc: svc 
    }); 
    })); 
    it('should assign data to scope', function() { 
    spyOn(svc, 'query').andCallThrough(); 
    deferred.resolve(data); 
    scope.$digest(); 
    expect(svc.query).toHaveBeenCalled(); 
    expect(scope.data).toBe(data); 
    }); 
}); 

我预计SVC的查询方法被调用,但显然还没有。

我跟着this指南嘲笑单元测试的承诺。

我在做什么错?

回答

28

看来我把我的间谍放在了错误的地方。当我把它放在beforeEach时,测试通过。

beforeEach(inject(function($controller, $rootScope, $q) { 
    svc = { 
     query: function() { 
     def = $q.defer(); 
     return def.promise; 
     } 
    }; 
    spyOn(svc, 'query').andCallThrough(); 
    scope = $rootScope.$new(); 
    controller = $controller('ctrl', { 
     $scope: scope, 
     svc: svc 
    }); 
    })); 
+2

尤其要注意spyOn()结束时的'andCallThrough'调用。 –

+0

您的控制器在实例化时调用服务方法,因此您必须在$ controller调用之前监视该服务方法。 – Richard

+0

你能展示完整的工作示例吗?我无法让这件事情起作用! :/ 我已经尝试了很多与上述不同的事情,但一切都返回undefined – SinSync

相关问题