在Angular中使用$ window和$ event的单元测试指令

时间:2015-06-11 20:42:12

标签: angularjs unit-testing angularjs-directive jasmine karma-jasmine

我有一个超级简单的指令,它会覆盖点击行为并在点击时重新加载整页。我在为这个指令编写单元测试时遇到了麻烦。看起来$window在运行测试时没有正确注入以及此错误:

TypeError: 'undefined' is not an object (evaluating '$event.preventDefault')

reload.directive.js

 angular.module('myModule')
    .directive('reload', ['$window', function($window) {
      return {
        restrict: 'A',
        scope: {},
        transclude: true,
        replace: true,
        template: '<a ng-click="reload($event)" ng-transclude></a>',
        link: function(scope, element, attrs) {
          scope.reload = function($event) {
            $event.preventDefault();
            $window.location.href = attrs.href;
          };
        }
      };
    }]);

我如何使用它的一个例子

<a ui-sref="home", reload>Home Example</a>

这是我的单元测试:reload-test.directive.js

describe('Testing reload directive', function() {
  beforeEach(module('myModule'));

  var window, element, scope;

  beforeEach(inject(function($compile, $rootScope, $window) {
    scope = $rootScope.$new();
    window = $window;
    element = $compile('<a reload href="/"></a>')(scope);
    scope.$digest();
  }));

  it('should reload the page with the right url', function() {
    var compiledElementScope = element.isolateScope();
    compiledElementScope.reload();
    expect(window.location.href).toEqual('/');
  });
});

已更新

我可以在触发整页重新加载的链接上使用target="_self",而不是执行任何操作。

1 个答案:

答案 0 :(得分:0)

如果您要触发某项活动,您的测试会更自然。

element.triggerHandler('click');

然后您的处理程序将由内部angular机制调用。

当您尝试更新window.location时,您的测试也会失败,因为它会导致整页重新加载。所以,你需要在这里模拟窗口:

var fakeWindow, element, scope;
beforeEach(module('myModule'));
beforeEach(function() {
    // define fake instance for $window
    module(function($provide) {
       fakeWindow = {location: {}};
       $provide.value('$window', fakeWindow)
    });
});

beforeEach(inject(function($compile, $rootScope) {
    scope = $rootScope.$new();
    element = $compile('<a reload href="/"></a>')(scope);
    scope.$digest();
}));

it('should reload the page with the right url', function() {
   var event = jasmine.createSpyObj('clickEvent', ['preventDefault']);
   event.type = 'click';
   element.triggerHandler(event)
   expect(fakeWindow.location.href).toEqual('/');
   expect(event.preventDefault).toHaveBeenCalled();
});

现在您可以安全地测试您的行为而没有副作用。