Как ввести службу в директиву unit test в 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.
Ответы
Ответ 1
Чтобы украсить, заглушить, предоставить mocks или переопределить любую данную услугу, вы можете использовать службу $provide
.
$provide.value
, $provide.decorator
и т.д. Документация здесь.
Затем вы можете сделать следующее:
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');
}));