我有一个超级简单的指令,它会覆盖点击行为并在点击时重新加载整页。我在为这个指令编写单元测试时遇到了麻烦。看起来$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"
,而不是执行任何操作。
答案 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();
});
现在您可以安全地测试您的行为而没有副作用。