I'm really confused trying to create test with the help of Jest documentation https://facebook.github.io/jest/docs/timer-mocks.html#content
I'm trying to check a state when container mounts and then few seconds later, after I have manually set values in the state (using setTimeout()).
I have a function inside Main's componentDidMount like this:
componentDidMount() {
this.setStateAfterDelay();
}
And what the function does is:
setStateAfterDelay = () => {
setTimeout(() => {
this.setState({ fruits: ['banana', 'apple', 'orange', 'vodka', 'kiwi'] });
}, 1500);
}
I achieved the first part with:
const component = mount(<Main />);
expect(component.state().fruits).toEqual(null);
But I have no clue how to check the state again after, lets say 2000ms?
Any help is appreciated :)
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();
});
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();
});
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.