Pass mock DOM event to directive handler without jQuery
Solution 1
At the current stable version of Angular, 1.3.14, you can do this without jQuery by passing the event as the first and only parameter of triggerHandler
, so instead of what was suggested in the question
element.triggerHandler('dragstart', new Event('dragstart'));
you can write
element.triggerHandler(new Event('dragstart'));
To add a spy on the preventDefault
function, as per the original question, you can do the following
var mockEvent;
beforeEach(function() {
mockEvent = new Event('dragstart');
spyOn(mockEvent, 'preventDefault');
});
it('should call preventDefault', function () {
element.triggerHandler(mockEvent);
expect(mockEvent.preventDefault).toHaveBeenCalled();
});
You can see this working in this Plunker. You can alternatively just use a plain object with at least a type
key, so in this case
mockEvent = {
type: 'dragstart',
preventDefault: jasmine.createSpy('preventdefault')
};
which can be seen working in this Plunker
I believe this was added to the 1.3 branch in this commit.
Solution 2
you may include jquery and create a jquery event object. this object can easly be passed:
beforeEach(function() {
mockEvent = $.Event('dragstart');
spyOn(mockEvent,'preventDefault');
});
it('should call preventDefault', function () {
element.triggerHandler(mockEvent);
expect(mockEvent.preventDefault).toHaveBeenCalled();
});
i have used this jquery version in your plunkr: //ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js
![Michal Charemza](https://i.stack.imgur.com/EP486.jpg?s=256&g=1)
Michal Charemza
A full-stack software engineer with experience in AngularJS, in-browser audio and video processing, Python, PHP, C++, and dev-ops. I particularly enjoy bringing designs to life with excellent UX, creating pragmatic and appropriately engineered solutions, profiling code to eliminate bottlenecks, incremental refactoring, functional programming, and slicing up large projects for quick and continual feedback.
Updated on July 24, 2022Comments
-
Michal Charemza almost 2 years
I have a very simple directive whose purpose is just to cancel the
dragstart
event:link: function(scope, element) { element.on('dragstart', function(e) { e.preventDefault(); }) }
How can I test this in a Jasmine test? I have the following test that attempts to spy on an Event object, and pass it to the handler:
var mockEvent; beforeEach(function() { mockEvent = new Event('dragstart'); spyOn(mockEvent,'preventDefault'); }); it('should call preventDefault', function () { element.triggerHandler('dragstart', mockEvent); expect(mockEvent.preventDefault).toHaveBeenCalled(); });
But the test fails. You can see this at this Plunker.. How can I test this (/refactor the directive to make it testable)?
Edit: Ideally without including jQuery. Edit: changed tags
-
Michal Charemza over 10 yearsI've added jQuery and changed the test at plnkr.co/edit/aRvgHQXPTCSvlXougxHX?p=preview , but the test is still failing.
-
michael over 10 yearselement.triggerHandler(mockEvent); not element.triggerHandler('dragstart' ,mockEvent);
-
Michal Charemza over 10 yearsAh, that works, including changing
$.Event
tonew Event
, as can be seen at plnkr.co/edit/2LrrEBjVjftXH5ueprLI?p=preview. Is there a way to do this without jQuery? -
Nacho Coloma about 7 yearsPlease edit your title or your answer to specify Angular. Others searching for vanilla JavaScript solutions are landing here.