SupremeTechnopriest / react-idle-timer

User activity timer component
https://idletimer.dev
MIT License
1.15k stars 143 forks source link

Is there any way to test useIdleTimer with Jest fake timers #274

Closed AlexHuman closed 2 years ago

AlexHuman commented 2 years ago

Question

Hi guys!

I'm having some issue with Jest. I use jest.useFake(); and jest.advanceTimersByTime(timerTime); instructions to check my onIdle handler goes right. It used to work for old <IdleTimer> component. However it dosn't work if i useuseIdleTimer.

Besides, I would not like to use await sleep(...) because it may cause a delay in the CI/CD pipeline.

Has anyone found a solution for this issue? Thanks for the future answers.

SupremeTechnopriest commented 2 years ago

Hi @AlexHuman, I don't know why I didn't get an alert for this issue, but yes there is a way. In a nut shell you need to useFakeTimers() and then createMocks(). Here is an example:

// test.setup.ts
import { createMocks } from 'react-idle-timer'
beforeAll(() => {
  jest.useFakeTimers()
  createMocks()
})

afterEach(() => {
  jest.clearAllTimers()
})

afterAll(() => {
  jest.useRealTimers()
})

// useIdleTimer.test.ts
it('Should use mocked timers', () => {
  props.timeout = 10000
  const { result } = idleTimer()
  expect(result.current.isIdle()).toBe(false)
  jest.advanceTimersByTime(10000)
  expect(result.current.isIdle()).toBe(true)
})

This will work for most of idle timer, but if you are using any of the get time methods, we will also need to fast forward the system clock. I have a branch locally where I'm switching all my tests to use fake timers. I will share my solutions on the docs when I'm done.