将模拟DOM事件传递给没有jQuery的指令处理程序

Mic*_*mza 14 unit-testing mocking jasmine angularjs karma-runner

我有一个非常简单的指令,其目的只是取消dragstart事件:

link: function(scope, element) {
  element.on('dragstart', function(e) {
    e.preventDefault();
  })
}
Run Code Online (Sandbox Code Playgroud)

如何在Jasmine测试中测试?我有以下测试试图窥探一个Event对象,并将其传递给处理程序:

var mockEvent; 

beforeEach(function() {
  mockEvent = new Event('dragstart');
  spyOn(mockEvent,'preventDefault');
});

it('should call preventDefault', function () {
  element.triggerHandler('dragstart', mockEvent);
  expect(mockEvent.preventDefault).toHaveBeenCalled();
});
Run Code Online (Sandbox Code Playgroud)

但测试失败了.你可以在这个Plunker看到这个..我如何测试这个(/重构指令使其可测试)?

编辑:理想情况下不包括jQuery.编辑:更改标签

mic*_*ael 11

您可以包含jquery并创建一个jquery事件对象.这个对象很容易传递:

beforeEach(function() {
  mockEvent = $.Event('dragstart');
  spyOn(mockEvent,'preventDefault');
});

it('should call preventDefault', function () {
  element.triggerHandler(mockEvent);
  expect(mockEvent.preventDefault).toHaveBeenCalled();
});
Run Code Online (Sandbox Code Playgroud)

我在你的plunkr中使用了这个jquery版本://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js

  • 应该接受这个答案. (2认同)

Mic*_*mza 9

在Angular的当前稳定版本1.3.14中,您可以通过将事件作为第一个也是唯一的参数传递而不使用jQuery triggerHandler,因此而不是问题中建议的内容

element.triggerHandler('dragstart', new Event('dragstart'));
Run Code Online (Sandbox Code Playgroud)

你可以写

element.triggerHandler(new Event('dragstart'));
Run Code Online (Sandbox Code Playgroud)

preventDefault根据原始问题在函数上添加间谍,您可以执行以下操作

var mockEvent; 

beforeEach(function() {
  mockEvent = new Event('dragstart');
  spyOn(mockEvent, 'preventDefault');
});

it('should call preventDefault', function () {
  element.triggerHandler(mockEvent);
  expect(mockEvent.preventDefault).toHaveBeenCalled();
});
Run Code Online (Sandbox Code Playgroud)

你可以在这个Plunker中看到这个.您也可以使用至少具有type键的普通对象,因此在这种情况下

mockEvent = {
  type: 'dragstart',
  preventDefault: jasmine.createSpy('preventdefault')
};
Run Code Online (Sandbox Code Playgroud)

可以看出在这个Plunker工作

我相信这已添加到此提交中的1.3分支.