Подтвердить что ты не робот

Как ввести службу в директиву 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.
4b9b3361

Ответ 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');

}));