Reputation: 2580
I'm posting this for those that still use PrototypeJS and want to test custom events using jasmine and jasmine-prototype plugin.
We're triggering custom events based on users clicks or form submits. We wanted a simple way to test that the custom events is fired correctly.
Here is an example:
var CustomEventsDispatcher = ( function() {
function init(){
//if elements exists
if($$('a.trigger_bomb')) {
// Observe the elements
$$(elements).each(function(element) {
element.observe('click', function(e) {
this.fire("bomb:explode", {})
});
});
}
return {'init' : init};
})();
Using resources available on the web, I've created a fixture ...
// spec/fixtures/links.html
<a class="trigger_bomb" href="#"> Trigger Bomb </a>
... and a test suite:
//spec/trigger_bomb_spec.js
describe("Trigger Bombs", function() {
beforeEach(function(){
loadFixtures("links.html")
CustomEventsDispatcher.init();
})
it("should raise the custom event", function(){
var element=$$('a.trigger_bomb').first();
spyOnEvent(element, 'click');
element.click();
expect('click').toHaveBeenTriggeredOn(element);
expect('bomb:explode').toHaveBeenTriggeredOn(element);
});
});
The first assertion works fine, but not the second. The reason is that spyOnEvent
alters the way click events are handled on element
.
Upvotes: 1
Views: 517
Reputation: 2580
The simplest way is to mock the fire
function like this:
//spec/trigger_bomb_spec.js
describe("Trigger Bombs", function() {
beforeEach(function(){
loadFixtures("links.html")
CustomEventsDispatcher.init();
})
it("should raise the custom event", function(){
var element=$$('a.trigger_bomb').first();
spyOn(element, 'fire')
element.click()
expect(element.fire).toHaveBeenCalledWith('bomb:explode', {})
});
});
However this solution has a side effect : the click will be executed which will cause the jasmine page result to reload continuously. You need to intercept click events and stop the default behavior with a global beforeEach
hook:
// spec/helpers/spec_helper.js
beforeEach(function(){
// stop all clicks from fixtures
// (but allow clicks from the user in the jasmine result page)
document.observe('click', function(e){
var element = e.findElement('#HTMLReporter')
if (element == document) {
Event.stop(e)
}
})
})
Hope this will help someone to save a few hours of debugging :). Feel free to comment / improve / propose a better alternative.
Upvotes: 1