0

How can I test to see that an event handler is bound to a node using JSUnit?

Here's what I have:

var mynode = document.getElementById( "mynode" );

assertNotNull( mynode );

MyLibrary.attachEvent( mynode, "click", function( ){ return true; } );

assertEquals( typeof mynode.onclick, typeof function( ){ return true; } );

But the type of mynode.onclick is, of course, object; while the typeof the function is..well...a function.

If I try just assertEquals( mynode.onclick, function( ){ return true; } ); the assertion also fails.

Any suggestions?

KeatsKelleher
  • 10,015
  • 4
  • 45
  • 52

2 Answers2

1

I don't know JSUnit, but how about using toString()?

assertEquals(mynode.onclick.toString(), "function( ){ return true; }");

Of course, there is an issue with string equality. But with a bit of effort, you could be able to get rid of all whitespaces in these two strings and compare without tabs, spaces, newlines...

I don't think you can compare methods/functions in javascript. If you want to compare two functions, you are in fact comparing their references. That means, once you state even exactly same function on different place in code, it is treated as different function (it has different address).

Check out this for more info about equality The Strict Equality Operators

EDIT: you can try to write the test this way, but there is still possibility of getting false:

var myHandler = function() { return true; };
MyLibrary.attachEvent( mynode, "click", myHandler);
assertEquals(mynode.onclick, myHandler);

since you're using exact same function, which has same reference in both cases you're using it. However, you must be careful about what MyLibrary.attachEvent does with passed reference to myHandler (like is it copying it? extending? just saving reference?...)

rdamborsky
  • 1,920
  • 1
  • 16
  • 21
  • If you call .toString() on the event that is set with addEventListener or attachEvent ( IE ) you get an error. mynode.onclick is not defined before or after attaching the event. If you print it out you can see it is a null object. – KeatsKelleher Mar 17 '11 at 14:55
  • MyLibrary.attachEvent( ) tests whether it should use attachEvent( ) (for IE) or addEventListener (for everything else). It then carries out the attachment. – KeatsKelleher Mar 17 '11 at 15:17
1

beware that the "onclick" property is not the same mechanism as addEventListener.

in your exemple, the mynode.onclick property is probably equal to null because the MyLibrary.attachEvent is using the addEventListener (standard compliant) / attachEvent (IE < 9) method. Hence you test :

typeof mynode.onclick = typeof null = "object"

Now your problem is that when the DOM Level 2 Events specification was written they forget to give an accessor to the list of events that are currently registered on a node. So basically you cannot write the unit test that you try to implement.

the DOM Level 3 Events specification (still in draft mode) addressed the problem in 2002 via a new property on the elements : eventListenerList

Unfortunately, the current draft seems to have removed this property and i don't think you will find a browser implementing it.

I could only find Firefox 3.6 implementing a getListenerInfoFor() method but it seems to be only available in chrome/XUL mode so it won't help.

you could either

  • wait for eventListenerList to be implemented in all browsers ;-)
  • trust that MyLibrary correctly adds the event
  • add a fake event with testing code inside the callback function and dispatch a click event on the element

I hope this will help you

Jerome Wagner

Jerome WAGNER
  • 21,986
  • 8
  • 62
  • 77