17

Up untill now I was used to write all my code inside the ready() function like:

$(document).ready(function() {
  // all my code
});

Now I see that with this approach, my code is not "unit testable", e.g. I cannot access the stuff inside ready() from QUnit.

What is the proper way to structure jQuery code that is compatible with using the ready() function and able to be tested?

Is there a good open source code base or project to study and learn from?

4 Answers 4

8

Have your code in the ready handler just calling functions outside of the ready handler:

$(document).ready(function() {
  // call some functions outside of handler
});

// most of my code

That way, you can call those functions for unit testing as well.


NB, there's a short-cut for $(document).ready:

$(function() {
  // call some functions outside of handler
});

// most of my code
Sign up to request clarification or add additional context in comments.

2 Comments

Is the "short-cut" you mention guaranteed to be executed after the DOM has loaded?
$(document).ready(function(){}); is identical to $(function(){}); in terms of functionality. They will both call the handlers either when the dom ready event is fired, or when they are evaluated if the dom ready event has already fired. From the jQuery docs: All three of the following syntaxes are equivalent: $(document).ready(handler), $().ready(handler) (this is not recommended), $(handler).
7

I see two approaches.

  1. Place the QUnit code inside document ready to run after your own code.

  2. Place your code in a module.

Option #2 looks like this:

var MyModule = (function() {
    // Your code
}());

$(document).ready(function() {
    // Quit tests, referring to MyModule.xxx
});

In option #2 it is true you do not get access to private elements within the module.

Ben Cherry talked about this a while ago in http://www.adequatelygood.com/2010/7/Writing-Testable-JavaScript where he actually made a controversial comment about closure-based privacy because of its impact on unit testing.

1 Comment

+1 but you dont have to wrap QUnit tests in a $(document).ready(function() { }); - QUnit already does that for you.
1

One of the most effective approaches is to structure your coding using JS "namespaces" and indeed you can get a great example from the jQuery core.

Comments

0

A strange approach that I took with untestable jQuery scripts goes like this:

  • install karma
  • include all the various scripts that can't be unit tested per se within the karma include files anyway
  • an syntax error introduced in a core script, for example, will fail the karma test, even if it's not unit tested
  • additionally if the scripts do create any globals, test for the presence of those globals in karma
  • finally refactor the scripts to have more callable units and run the tests in karma

So start with a browser run to at least sanity check!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.