web-dev-qa-db-ja.com

jQueryを使用せずにモックDOMイベントをディレクティブハンドラーに渡す

dragstartイベントをキャンセルすることだけを目的とした非常に単純なディレクティブがあります。

link: function(scope, element) {
  element.on('dragstart', function(e) {
    e.preventDefault();
  })
}

ジャスミンテストでこれをテストするにはどうすればよいですか? 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();
});

しかし、テストは失敗します。あなたは このプランカーでこれを見てください。 。これをテストするにはどうすればよいですか(/ディレクティブをリファクタリングしてテスト可能にします)?

編集:理想的にはjQueryを含めないでください。編集:タグを変更

15
Michal Charemza

Angularの現在の安定バージョン1.3.14では、イベントをtriggerHandlerの最初で唯一のパラメーターとして渡すことで、jQueryなしでこれを行うことができるため、質問で提案されたものの代わりに

element.triggerHandler('dragstart', new Event('dragstart'));

あなたは書ける

element.triggerHandler(new Event('dragstart'));

元の質問のように、preventDefault関数にスパイを追加するには、次のようにします。

var mockEvent; 

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

it('should call preventDefault', function () {
  element.triggerHandler(mockEvent);
  expect(mockEvent.preventDefault).toHaveBeenCalled();
});

あなたは このプランカーでこれが機能しているのを見てください 。または、少なくともtypeキーを持つプレーンオブジェクトを使用することもできます。この場合、

mockEvent = {
  type: 'dragstart',
  preventDefault: jasmine.createSpy('preventdefault')
};

見ることができます このプランカーで働いています

これは このコミット の1.3ブランチに追加されたと思います。

9
Michal Charemza

jqueryを含めて、jqueryイベントオブジェクトを作成できます。このオブジェクトは簡単に渡すことができます:

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

it('should call preventDefault', function () {
  element.triggerHandler(mockEvent);
  expect(mockEvent.preventDefault).toHaveBeenCalled();
});

私はあなたのプランカーでこのjqueryバージョンを使用しました://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js

11
michael