Luke Willis
Luke Willis

Reputation: 8580

Why is my async Jest test not failing when it should?

I have some asynchronous actions that I need to test with Jest. My test is currently passing when it should fail.

describe('Asynchronous Code', () => {
  it('should execute promise', () => {
    console.log(1);
    someFunctionThatReturnsAPromise()
      .then(() => {
        console.log(2);
        expect(true).toBeFalsy();
        console.log(3);
      });
    console.log(4);
  });
});

When I run npm test, I get the following output:

PASS  __tests__/Async.test.js
 ● Console

   console.log __tests__/Async.test.js:3
     1
   console.log static-content-test/react/actions/DashboardActions.test.js:6
     2
   console.log static-content-test/react/actions/DashboardActions.test.js:10
     4

As you can see, the test is passing, but console.log(3) is never executed because true is not falsy, and the expectation fails.

How can I get Jest to recognize my expectations inside async callbacks?

Upvotes: 6

Views: 4844

Answers (3)

varaprasadh
varaprasadh

Reputation: 505

Here is the alternate solution.

Jest will be terminated once it reaches the end of context. So you need to return the promise from the callback to tell it to wait for the promise to get resolved and tested.

Lets say there is a promise

const promise=fetch("blah.com/api")

test("should return valid data",()=>{
   return expect(promise).resolves.toBeTruthy() 
})

.resolves waits for the promise to resolve, and you apply appropriate matchers as your wish.

And also you can use .rejects when you are checking for the error cases.

Upvotes: 1

Luke Willis
Luke Willis

Reputation: 8580

Alternatively, you can follow the done pattern as described here:

it('should execute promise', (done) => {
  someFunctionThatReturnsAPromise()
    .then(() => {
      expect(true).toBeFalsy();
      done();
    });
});

This will work with Jest, but is more commonly used with Jasmine and Mocha.

Upvotes: 3

Luke Willis
Luke Willis

Reputation: 8580

When testing asynchronous code, you need to return the promise from the test. Change the test body to:

return someFunctionThatReturnsAPromise()
  .then(() => {
    expect(true).toBeFalsy();
  });

With that, the test fails as expected:

FAIL  __tests__/Async.test.js
 ● Asynchronous Code › should execute promise

   expect(received).toBeFalsy()

   Expected value to be falsy, instead received
     true

This is the pattern facebook uses for testing async code with jest.

Upvotes: 13

Related Questions