Reputation: 1001
I'm experimenting with Jest to unit test an angular application. In order to test the angular bindings I'm trying to use jsdom (N.B. I'm using v3.1.2 as I'm using node not IO). When I need to load a script with the html the test seems to complete before the script is loaded.
I've simplified my test case to use an example from jsdom:
it('updates the view without error', function(){
var jsdom = require('../../../../node_modules/jsdom/lib/jsdom');
jsdom.env(
'<p><a class="the-link" href="https://github.com/tmpvar/jsdom">jsdom!</a></p>',
["http://code.jquery.com/jquery.js"],
function (errors, window) {
//console.log("contents of a.the-link:", window.$("a.the-link").text());
console.log("Completed");
expect(errors).toBeNull();
}
);
console.log('exiting...');
});
If I run this test, the test will pass but the "Completed" log message will not be printed, I can also replace the expect with something that should obviously fail, like expect(false).toBeTruthy() and the test will still "pass". If I remove the injection of jquery then all works as expected.
How should I make sure that the script is loaded before I exit the test? And more generally, using jsdom explicitly with Jest feels a bit wrong. Is there a better way?
Upvotes: 2
Views: 5918
Reputation: 2059
I think the best way to test asynchronous code is to pass the 'done' callback as explained in the docs. Your code would then become:
it('updates the view without error', function(done){
var jsdom = require('../../../../node_modules/jsdom/lib/jsdom');
jsdom.env(
'<p><a class="the-link" href="https://github.com/tmpvar/jsdom">jsdom!</a></p>',
["http://code.jquery.com/jquery.js"],
function (errors, window) {
//console.log("contents of a.the-link:", window.$("a.the-link").text());
console.log("Completed");
expect(errors).toBeNull();
done();
}
);
console.log('exiting...');
});
Upvotes: 1
Reputation: 816282
Because .env
is probably asynchronous, the test will always exist before the callback is called.
According to the jest tutorial, you can simply assign the HTML to document.body.innerHTML
:
// Set up our document body
document.body.innerHTML =
'<div>' +
' <span id="username" />' +
' <button id="button" />' +
'</div>';
var $ = require('jquery');
Alternatively you could use pit
instead of it
and return a promise from the function.
Upvotes: 5