I've created a Countdown timer component and am writing out tests. I want to test that the setInterval
gets cleared when the distance
is less than 0.
I've set up a test as follows using vi.spyOn(global, 'clearInterval')
:
test('should clear the interval when the distance is less than 0', () => {
const date = setDate(SECOND);
vi.spyOn(global, 'clearInterval');
render(<CountdownClock endDate={date} etc.../>)
act(() => {
vi.runOnlyPendingTimers();
vi.runOnlyPendingTimers();
vi.clearAllMocks();
});
// expect assertions ...
});
The code itself handles the timer inside of a useEffect:
useEffect(() => {
// Start straight away (ie before first second elapses in setInterval)
if (distance() > 0) {
runTimer();
}
const interval = setInterval(() => {
if (distance() < 0) {
// Stop Timer
endTimer();
clearInterval(interval);
} else {
runTimer();
}
}, 1000);
return () => {
clearInterval(interval);
};
}, []);
The above test sets the date to 1 second in the future and then I run setInterval twice more using vi.runOnlyPendingTimers()
. This pushes the distance into negative which stops the timer and clears the interval.
I've logged this out and I can see that the spy works in this part of the code - I can see callCount of 1
after clearInterval
has run.
The issue I get is that it then runs the useEffect return statement to clear up. At this point I get the error:
ReferenceError: clearInterval is not defined
❯ src/components/CountdownClock/CountdownClockContainer.tsx:94:12
92|
93| return () => {
94| clearInterval(interval);
| ^
95| };
I can't work out why clearInterval
is undefined
at this stage. My understanding is that spyOn
doesn't create a mock and is rather 'spying' on the method so I can't figure out why clearInterval
becomes undefined
.
If anyone has any suggestions as to what might be the issue that would be great.