Search code examples
javascriptnode.jsecmascript-6jestjses6-promise

Why is a mocked jest promise not rejected with allSettled?


I want to test a method which returns the result of Promise.allSettled() and calls another function which returns promises.

I reduced the problem to the following test code:

  describe('Promise tests', () => {
    it('should reject directly', async () => {
      const f = jest.fn().mockRejectedValue(new Error('foo'));
      const p = async () => await f();

      // works
      await expect(p).rejects.toThrow('foo');
    });

    it('should reject with allSettled', async () => {
      const f = jest.fn().mockRejectedValue(new Error('foo'));
      const p = async () => await f();

      const results = await Promise.allSettled([p]);
      expect(results[0].status).toBe('rejected'); // fulfilled - but why?
      expect(results[0].reason).toBe('foo');
    });
  });

Why is the second case not receiving a rejected promise?

  • node.js v14.3.0
  • jest v25.4.0

Solution

  • You are almost there. Promise.allSettled expects to receive an array of Promises not an array of functions returning a promise, which in fact is what your constant p does.

    By simply calling the p() you solve your issue:

      describe('Promise tests', () => {
        it('should reject directly', async () => {
          const f = jest.fn().mockRejectedValue(new Error('foo'));
          const p = async () => await f();
    
          // works
          await expect(p()).rejects.toThrow('foo');
        });
    
        it('should reject with allSettled', async () => {
          const f = jest.fn().mockRejectedValue(new Error('foo'));
          const p = async () => await f();
    
          const results = await Promise.allSettled([p()]);
          expect(results[0].status).toBe('rejected'); // fulfilled - but why?
          expect(results[0].reason).toBe('foo');
        });
      });
    

    By the way: My linter complains about unnecessary awaits :-)