I am writing a react application, and also its unit test cases. I am facing a very odd scenario, wherein I am trying to spy on the setInterval ( or setTimeout ) which is placed inside a function, but it is not being called in my test
Following is my code :
// useInterval.js - Oversimplified version
export const useInterval = () => {
setInterval(() => {
console.log("called");
}, 1000);
};
// useInterval.test.js
describe("Test Interval", () => {
let spyOnSetInterval = null;
beforeEach(() => {
jest.useFakeTimers();
spyOnSetInterval = jest.spyOn(global, 'setInterval');
});
afterEach(() => {
jest.restoreAllMocks();
jest.useRealTimers();
});
it("checking to see if setInterval is called", () => {
useInterval(); // already imported in the current file.
jest.advanceTimersByTime(1000);
expect(spyOnSetInterval).toBeCalled();
});
});
Output
expect(jest.fn()).toBeCalled()
Expected number of calls: >= 1
Received number of calls: 0
18 | useInterval();
19 | jest.advanceTimersByTime(1000);
> 20 | expect(spyOnSetInterval).toBeCalled();
| ^
21 | });
22 | })
What am I doing wrong here ? If I spy on the console.log also which is inside the setInterval, it is never called. However, if I place console.log outside setInterval and spy on console.log, then it is working fine.
At the end, I need to write test cases to check that setInterval is being called.
Tried :
-
jest.advanceTimersByTime(5000); // To make sure setInterval is being called multiple times
- jest.runAllTimers() // Even though this should not work since interval is infinite.
- Tried using Jest v26 and v29
- Tried using jest.useFakeTimers('legacy'); with jest v29
- Tried using simon API but that also didnt work
Update If I use jest.useFakeTimers(), it doesnt work. However, if I alternatively use "timers":"fake" in jest global config file, this starts working. why is jest.useFakeTimers() not working for me ? I tried placing it in beforeEach / beforeAll / start of describe statement / top of file.