Friday, October 12th, 2007

Testing JavaScript Objects with Function.prototype.call and Crosscheck

Category: JavaScript, Testing, Tip

Jason Harwig has written a quick tip on Testing JavaScript Objects with Function.prototype.call. The example that he uses is:

javascript

  1. /**
  2.  * Call a function with the given execution context and parameters.
  3.  * @param <object> instance the object to use as the "this" inside the function
  4.  * @param <array of Objects> parameters the objects to pass to the function
  5.  */
  6. Function.prototype.call(instance, parameters...);
  7.  
  8. var x = { message: 'Hello World' };
  9. var hello_function = function(name) {
  10.   alert(this.message + ", " + name);
  11. }
  12. hello_function.call(x, 'jason');

In the context of Crosscheck, the JavaScript unit testing framework, you would see this work via:

javascript

  1. // function to test
  2. String.prototype.trim = function() {
  3.    return this.replace(/^\s+|\s+$/g,'');
  4. }
  5.  
  6. // crosscheck test
  7. assertTrim: function() {
  8.    assertEquals('text', String.prototype.trim.call('  text');
  9.    assertEquals('text', String.prototype.trim.call('  text  \n ');
  10. }

What is Crosscheck?

Crosscheck is an open source testing framework for verifying your in-browser javascript. It helps you ensure that your code will run in many different browsers such as Internet Explorer and Firefox, but without needing installations of those browsers. The only thing you need is a Java Virtual Machine.

Posted by Dion Almaer at 7:55 am
5 Comments

+++--
3.5 rating from 26 votes

5 Comments »

Comments feed TrackBack URI

I have also added a simple testing method, known from python as DocTest as a patch to dojo (should be easy to adapt to other frameworks). You can find it here http://trac.dojotoolkit.org/ticket/4651 its still only a ticket for dojo.

wolfram

Comment by Wolfram Kriesing — October 12, 2007

It’s good to write tests, of course, but I don’t see what Function.prototype.call() brings to the party.

This code:


assertTrim: function() {
assertEquals('text', String.prototype.trim.call(' text') );
assertEquals('text', String.prototype.trim.call(' text \n ') );
}

could be written:


assertTrim: function() {
assert( ' text'.trim() == 'text' );
assert( ' text \n '.trim.call() == 'text' );
}

That seems much more straightforward and to the point. It uses method calls that look like the real thing (because they are), and it should be just as fast as the more lengthy version.

If I missed something here, I’d be grateful to anyone who could set me straight. Thanks!

Comment by Michael Geary — October 12, 2007

Typo in my comment above. The second version should read:


assertTrim: function() {
assert( ' text'.trim() == 'text' );
assert( ' text \n '.trim() == 'text' );
}

Short and sweet!

Comment by Michael Geary — October 12, 2007

Michael,

I agree that the string case is one where there isn’t any benefit to using call, but with a custom object that did many things in the constructor would make testing easier.

As I stated in the blog, the object I was testing did a lot of DOM scripting in the constructor and I didn’t care to mock that in every instance function test.

Comment by Jason Harwig — October 12, 2007

i have one site with a lot of ajaxscript. Mabey it is usefull for the readers of this blog.

http://scripts.ajaxflakes.com/

Comment by jest staffel — October 14, 2007

Leave a comment

You must be logged in to post a comment.