testingjestjsmockingdelay

Jest testing :mockResolveValue with delay


How to mockReturnValue with delay in jest testing?

The intention of this test is to mock method as unsettled on flushpromise. Let's say,

There are two possible way , we can achieve this by

  1. making mockReturnValue return empty promise.
  2. using jeskfaketimer to delay the mockReturnvalue

Both the above option is expected to give unsettled promise on assertion.

Although, The second option doesn't seem working with following code. Any input is appreciated.

Tried the following code.

import callout from ".../callout.."

jest.mock(
"../callout..",
()=>{
    return{
         default:jest.fn(),
         };
    },
    {virtual: true}
);

const { setImmediate } = require("timers");

function flushPromises()
{
  return new Promise((resolve)=> setImmediate(resolve));
}


it("test delay", async()=>{
       jest.useFakeTimers();

       callout.mockResolvedValue(()=> Promise(resolve=>setTimeout(()=>resolve(),2000)));

       jest.advanceTimersByTime(20);

       await flushpromises();
       expect(callout).not.toHavebeencalled();

       jest.advanceTimersByTime(2000);
       expect(callout).toHavebeencalled();
});

Solution

  • I am able to resolve the issue with the following change.

    Basically, I replaced the setTimeout with a wait custom function as shown below.

    import callout from ".../callout..";
    
    jest.mock(
      "../callout..",
      () => {
        return {
          default: jest.fn(),
        };
      },
      { virtual: true }
    );
    
    const { setImmediate } = require("timers");
    
    function flushPromises() {
      return new Promise((resolve) => setImmediate(resolve));
    }
    
    function wait(ms, value) {
      return new Promise((resolve) => setTimeout(resolve, ms, value));
    }
    
    it("test delay", async () => {
      jest.useFakeTimers();
      let response = JSON.stringify({ status: 200, data: true });
      callout.mockReturnValueOnce(wait(2000, response));
      jest.advanceTimersByTime(20);
      await flushpromises();
      expect(callout).not.toHavebeencalled();
      jest.advanceTimersByTime(2000);
      expect(callout).toHavebeencalled();
    });