我正在尝试对一个简单的指令进行单元测试,如下所示:
angular.module('blog').directive('imageOnLoad', function() {
return {
restrict: 'A',
link: function(scope, element, attrs, fn) {
element.bind('load', function() {
scope.$emit('resizeContent');
});
}
};
});
我可以看到需要在这里测试的两件事是它绑定到图像加载事件,该事件进而发出 resizeContent 事件。
我的单元测试中有以下内容 - 目前只是测试事件绑定:
describe('imageOnLoad', function() {
beforeEach(module('blog'));
var scope,compile, element;
beforeEach(inject(function($rootScope,$compile) {
scope = $rootScope.$new();
compile = $compile;
var elementString = '<img ng-src="123.jpg" image-on-load />';
element = $compile(elementString)(scope);
}));
it('should bind to the load event of the image', function() {
spyOn(element, 'bind').andCallThrough();
expect(element.bind).toHaveBeenCalled();
});
});
我的问题:加载事件似乎永远不会触发。我的第一个猜测是,这是因为 123.jpg 图像不存在 - 如果是这样,我的问题是如何模拟它,这样我就不必在那里携带物理图像文件。
成功了,这也是我设置顺序的问题。它通过调用隐式测试图像加载事件绑定。这是工作代码:
describe('imageOnLoad', function() {
beforeEach(module('blog'));
var scope,compile, element;
beforeEach(inject(function($rootScope,$compile) {
scope = $rootScope.$new();
compile = $compile;
element = angular.element('<img ng-src="123.jpg" image-on-load />');
$compile(element)(scope);
}));
it('should emit the resizeContent signal when the load event occurs', function() {
spyOn(scope, '$emit');
element.trigger('load');
expect(scope.$emit).toHaveBeenCalledWith('resizeContent');
});
});
element = $compile(elementString)(scope);
在那行之后立即尝试 - 应该可以:
element.trigger('load');
测试 jQuery Noodle 并不是什么好主意。
您可以通过选择图像元素来模拟加载事件,并使用您想要的任何事件调用triggerEventHandler。
例如这是一张图片
<img hidden [src]="this.imgService.getImage()" (load)="imgLoaded()" />
如果您想模拟 load 事件来测试 imgLoaded() 方法,您可以
it('imgLoaded should be called when image is preloaded', () => {
spyOn(component, 'imgLoaded').and.callThrough();
fixture.detectChanges();
const preloadImage = debugElement.query(
By.css('img')
);
preloadImage.triggerEventHandler('load')
expect(component.imgLoaded).toHaveBeenCalledOnceWith();
});