Using Jasmine's done() Callback for Asynchronous Tests
Learn how to use Jasmine's done() callback to properly test asynchronous code, with a worked example, explanation of Jasmine's waiting mechanism, and common pitfalls to avoid.
22 May 2026, 04:29 UTC

When to use done()
To test asynchronous code in Jasmine, pass a done callback to the test function and invoke it when the async work finishes. Jasmine will not proceed to the next spec until done is called (or the default timeout expires).
Basic syntax
it('fetches user data', function(done) {
// Assume fetchUser returns a Promise
fetchUser(123)
.then(user => {
expect(user.id).toBe(123);
done(); // signal success
})
.catch(err => {
done.fail(err); // signal failure with error details
});
});
How Jasmine waits for done()
When the test function receives a done argument, Jasmine changes its completion criteria:
- The spec is considered pending until
doneis invoked. - If
doneis not called within the default timeout (5 seconds), Jasmine fails the spec with a timeout error. - Calling
donemore than once, or after Jasmine has already moved on, throws an error to prevent false‑positive passes.
Limits and common mistakes
- Omitting the parameter – If you write
it('test', function() { ... })withoutdone, Jasmine treats the test as synchronous. Any asynchronous work will likely finish after the spec ends, causing a silent pass or a timeout that is hard to trace. - Using arrow functions – Arrow functions lexically bind
thisand do not alter theargumentsobject. Writingit('test', () => { ... })prevents Jasmine from injecting adonecallback, leading to the same issue as omitting the parameter. - Mixing done() with async/await – Returning a promise or using
asyncalready signals completion. Adding adonecall in addition can cause race conditions; the test may finish twice, triggering Jasmine’s error about multiple calls. - Failing to handle errors – Forgetting to call
done.failin a.catchblock leaves Jasmine waiting fordonethat never arrives, resulting in a timeout.
To verify behavior, create a fresh Node project, install Jasmine (npm install --save-dev jasmine), run jasmine init, add a spec file with the example above, and execute jasmine. Observe a passing test when the promise resolves, a failure when it rejects, and a timeout when done is omitted or called twice.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.