使用jasmine在Angular控制器中模拟服务依赖项

时间:2015-01-21 15:11:05

标签: angularjs unit-testing jasmine

我一直试图开始使用业力和茉莉花进行角度单位测试,并且我一直在试着绕着如何测试具有依赖关系的控制器。我尝试用茉莉花spyObj嘲笑一个间谍并在beforeEach钩子中注册它,但由于某种原因间谍没被识别。

以下是代码:

angular.module('testModule', [])
.controller('TestController', [
    '$scope',
    'TestService',
    function ($scope, TestService) {
        $scope.data = TestService.load();
    }])

.factory('TestService', function () {
    return {
        load: function(){
            return "foo";
        }
    }
});

这是测试

describe('TestController', function() {

var $controller, $scope, TestService;

beforeEach(module('testModule'), function($provide){
    TestService = jasmine.createSpyObj("TestService", ["load"]);
    TestService.load.andReturn("bar");
    $provide.value("TestService", TestService)
});

beforeEach(inject(function(_$controller_, $rootScope, _TestService_) {
    $scope = $rootScope.$new();
    TestService = _TestService_;
    $controller = _$controller_('TestController', {
        $scope: $scope,
        TestService: TestService
    });
}));

it('should set $scope.data to bar when TestService.load is called', function() {
    expect(TestService.load).toHaveBeenCalled();
    expect($scope.data).toEqual("bar");
}); });

测试中的两个断言都失败了。

我得到错误:期待一个间谍,但得到了功能'当我调用expect(TestService.load).toHaveBeenCalled();

如果我调用expect($ scope.data).toEqual(" bar"),我会得到预期的#foo'等于' bar' "富"来自实际的服务,而不是间谍对象。

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

beforeEach _TestService_注入beforeEach,然后通过以下内容覆盖您在之前的TestService = _TestService_; 中声明的那个:

$provide.value("TestService", TestService)

删除该代码,您的测试应该会成功。

也没有必要这样做:

{{1}}

基本上,当你手动注入不必要的东西时,你会尝试使用Angular的依赖注入。

答案 1 :(得分:1)

使用jasmine.createSpyObj提供的现有服务,然后只是模拟单个方法,而不是$injector,而不是spyOn。您可以使用describe('TestController', function() { var $controller, $scope, TestService; beforeEach(module('testModule')); beforeEach(inject(function(_$controller_, $rootScope, _TestService_) { $scope = $rootScope.$new(); TestService = _TestService_; spyOn(TestService, 'load').and.returnValue('bar'); $controller = _$controller_('TestController', { $scope: $scope, TestService: TestService }); })); it('should set $scope.data to bar when TestService.load is called', function() { expect(TestService.load).toHaveBeenCalled(); expect($scope.data).toEqual("bar"); }); }); 来实现此目的:

{{1}}