Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jest: async test incorrectly passes despite mismatched expect/received values

The following test in Jest should not pass:

const targetFile = require("../targetFile.js");
fetch = jest.fn(() => Promise.resolve('file scoped default value'));

test('diffFileFetch', () => {
  fetch.mockImplementation(() => new Promise((resolve, reject) => {
    resolve('wrong value');
  }));

  targetFile.diffFileFetch()
    .then(async data => {
      await expect(data).toEqual('correct value');
    })
    .catch(e => console.log(e, `=====e=====`));
});

The catch block fires but the test still passes. What is the cause of this and how should it be fixed?

PASS  
views/admin/__tests__/CurrentCouponListingSection.test.js
  ✓ diffFileFetch (6ms)

 console.log views/admin/__tests__/testFile.test.js:59
    { Error: expect(received).toEqual(expected) // deep equality

    Expected: "correct value"
    Received: "wrong value"
        at targetFile.diffFileFetch.then (/var/www/html/wptest2/wp-content/plugins/fvc/views/admin/__tests__/testFile.test.js:58:1)
        at <anonymous>
        at process._tickCallback (internal/process/next_tick.js:188:7)
      matcherResult: 
       { actual: 'wrong value',
         expected: 'correct value',
         message: [Function],
         name: 'toEqual',
         pass: false } } '=====e====='

Also tried

Removing async/await from .then(). No difference.

like image 594
Sean D Avatar asked Jun 08 '19 13:06

Sean D


1 Answers

The test is finishing before the Promise callback runs so it passes...and then the error gets logged.

If a test includes asynchronous code then you need to either use done:

test('diffFileFetch', done => {  // <= use done
  fetch.mockImplementation(() => new Promise((resolve, reject) => {
    resolve('wrong value');
  }));

  targetFile.diffFileFetch()
    .then(data => {
      expect(data).toBe('correct value');
      done();  // <= now call done
    })
});

...return the Promise:

test('diffFileFetch', () => {
  fetch.mockImplementation(() => new Promise((resolve, reject) => {
    resolve('wrong value');
  }));

  return targetFile.diffFileFetch()  // <= return the Promise
    .then(data => {
      expect(data).toBe('correct value');
    })
});

...or use an async test function and await the Promise:

test('diffFileFetch', async () => {  // <= async test function
  fetch.mockImplementation(() => new Promise((resolve, reject) => {
    resolve('wrong value');
  }));

  const data = await targetFile.diffFileFetch()  // <= await the Promise
  expect(data).toBe('correct value');
});
like image 164
Brian Adams Avatar answered Oct 03 '22 18:10

Brian Adams