Reputation: 407
Jest's docs provides a negative example of what not to do when testing asynchronous code. I implemented it this way:
const expect = require('expect');
function fetchData(cb) {
setTimeout(cb('peanut butter2'), 1500);
}
test('the data is peanut butter', () => {
function callback(data) {
expect(data).toBe('peanut butter');
}
fetchData(callback);
});
I ran npx jest test.js
, and this was the output:
Fabians-MacBook-Pro:playground fabian$ npx jest test.js
FAIL ./test.js
✕ the data is peanut butter (6ms)
● the data is peanut butter
expect(received).toBe(expected)
Expected value to be (using Object.is):
"peanut butter"
Received:
"peanut butter2"
at callback (playground/test.js:9:22)
at fetchData (playground/test.js:4:16)
at Object.<anonymous>.test (playground/test.js:12:5)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 0.866s, estimated 1s
Ran all test suites matching /test.js/i.
I don't understand the results.
Why does it work even though I didn't call done(), as Jest recommends you do for testing asynchronous code? I'm pretty sure setTimeout is asynchronous, because I tested it in a blank test script using console.log() statements, and the second one fired before the first one which was enclosed in a setTimeout function.
Furthermore, the test failed in 0.866s, when my timeout was set to 1500ms. How could Jest have received the incorrect callback data (peanut butter2) when my callback should not even have been called?
Upvotes: 0
Views: 120
Reputation: 1491
Because your test looks like it should be async
, but is actually synchronous
due to an error in your code.
You've got the following, which looks like it's designed to call the method cb
after 1500ms
, but you're calling cb
immediately:
setTimeout(cb('peanut butter2'), 1500);
Which in turn passes the string
into your callback
function which runs the expect
immediately/synchronously.
What you probably wanted was something like:
setTimeout(function() { cb('peanut butter2') }, 1500);
Or alternatively, to have setTimeout
pass the arg into your cb
function and call it:
setTimeout(cb, 1500, 'peanut butter2')
Which would actually call your cb
function after 1500ms
, as expected.
Upvotes: 1