2013-04-01 106 views
26

我需要测试一个指令,该指令对一些注入的服务执行一些调用。 以下代码段是一个示例指令,用于监听事件,并在指定元素内按下Enter时重定向浏览器。如何在AngularJS的指令单元测试中注入服务

编辑:我觉得我可能在E2E测试土地上涉水?

angular.module('fooApp') 
    .directive('gotoOnEnter', ['$location', function ($location) { 

    var _linkFn = function link(scope, element, attrs) { 

     element.off('keypress').on('keypress', function(e) { 
        if(e.keyCode === 13) 
        { 
         $location.path(scope.redirectUrl); 
        } 
       }); 
    } 

    return { 
     restrict: 'A', 
     link: _linkFn 
    }; 
    }]); 

的问题是,我还没有想出如何注入服务的指示对他们的间谍。

我建议的解决方案如下所示: 由于我没有设法成功注入$locacion服务进行侦察,因此它无法正常工作。

describe('Directive: gotoOnEnter', function() { 
    beforeEach(module('fooApp')); 

    var element; 

    it('should visit the link in scope.url when enter is pressed', inject(function ($rootScope, $compile, $location) { 

    element = angular.element('<input type="text" goto-on-enter>'); 
    element = $compile(element)($rootScope); 

    $rootScope.redirectUrl = 'http://www.google.com'; 
    $rootScope.$digest(); 

    var e = jQuery.Event('keypress'); 
    e.keyCode = 13; 
    element.trigger(e); 

    spyOn($location, 'path'); 

    expect($location.path).toHaveBeenCalledWith('http://www.google.com'); 
    })); 

这就产生

Expected spy path to have been called with [ 'http://www.google.com' ] but it was never called. 
+0

你需要尝试浏览之前创建的间谍。我相信,如果您将调用“spyOn”移至该函数的顶部,它将按预期工作。 –

回答

35

为了装饰,存根,提供嘲笑或覆盖任何给定的服务,您可以使用$provide服务。 $provide.value,$provide.decorator等。文档here

然后,你可以做这样的东西:

var $location; 

beforeEach(function() { 
    module('studentportalenApp', function($provide) { 
     $provide.decorator('$location', function($delegate) { 

     $delegate.path = jasmine.createSpy(); 

     return $delegate; 
     }); 
    }); 

    inject(function(_$location_) { 
     $location = _$location_; 
    }); 

    }); 

...

it('should visit the link in scope.redirectUrl when enter is pressed', inject(function ($rootScope, $compile, $location) { 
    element = angular.element('<input type="text" goto-on-enter>'); 
    element = $compile(element)($rootScope); 

    $rootScope.redirectUrl = 'http://www.google.com'; 
    $rootScope.$digest(); 

    var e = jQuery.Event('keypress'); 
    e.keyCode = 13; 
    element.trigger(e); 

    $rootScope.$digest(); 

    expect($location.path).toHaveBeenCalledWith('http://www.google.com'); 

})); 
+0

文档链接已更改:https://docs.angularjs.org/api/auto/object/$provide – primavera133

+0

再次更改:https://docs.angularjs.org/api/auto/service/$provide –