score:48

Accepted answer

I haven't really tested this code. But, something similar to this should work I think.

const fruits = ['banana', 'apple', 'orange', 'vodka', 'kiwi'];

it('mock setTimeout test', () => {
 jest.useFakeTimers();
 setTimeout(() => {
   expect(component.state().fruits).toEqual(fruits);
 }, 1500);
 jest.runAllTimers();
});

score:0

I know this is question about how to check something after 20 seconds. But this might be also an indicator that you don't want to test 20 seconds, since what's important sometimes is whether certain action has been performed with the right inputs. In this case, you could restructure your code a bit so that you can pass in a dispatch function. For instance

    function abc() {
        return dispatch => {
            return Promise.then(res => {})  // this would take 20 seconds
        }
    }

Because dispatch is passed in, therefore you can easily use the following in the testing code.

    const dispatch = Jest.fn()
    abc(dispatch)
    expect(dispatch).toBeCalled()

Of course the assumption is that you do not care about if it's 20 seconds, instead you care more about the workflow process.

score:13

You don't need to delay your tests, simply calling jest.runAllTimers() before asserting, will work.

const fruits = ['banana', 'apple', 'orange', 'vodka', 'kiwi'];

it('initializes the fruits state', () => {
 jest.useFakeTimers();
 jest.runAllTimers();
 expect(component.state().fruits).toEqual(fruits);
});

You could also call useFakeTimers() in a beforeEach if you are going to test multiple times and also runAllTimers() could be inside another beforeEach so you don't repeat yourself.

score:82

while jest can run async code easily, you can use promise and setTimeout combination to wait a bit. For example this code will wait for 2 seconds:

await new Promise((r) => setTimeout(r, 2000));

Full sample test. Don't forget to add async flag before the callback function:

test('some test title', async () => {
  const foo = true;
  await new Promise((r) => setTimeout(r, 2000));
  expect(foo).toBeDefined();
});

Also, keep in mind that default "timeout" is 5 seconds (5000ms). If your test may run longer, you can add jest.setTimeout(30000); above the test(). 30000 will make sure to not timeout for 30 seconds. You can add any number you need. Full example with setTimeout:

jest.setTimeout(30000);

test('some test title', async () => {
  const foo = true;
  await new Promise((r) => setTimeout(r, 2000));
  expect(foo).toBeDefined();
});

Related Query

More Query from same tag