Skip to content

calling jest.useFakeTimers() causes problems #244

@dadamssg

Description

@dadamssg
  • react-testing-library version: 5.3.1
  • react version: react@16.7.0-alpha.2
  • node version: 8.12.0
  • npm (or yarn) version: yarn 1.10.1

Relevant code or config:

import React, {useEffect, useReducer} from 'react'
import {render, waitForElement, flushEffects} from 'react-testing-library'

jest.useFakeTimers()

const initialState = {
  loading: false,
  slides: [],
  currentId: null
}

function reducer (state, action) {
  switch (action.type) {
    case 'FETCHING_SLIDES_REQUEST':
      return {...initialState, loading: true}
    case 'FETCHING_SLIDES_SUCCESS':
      return {
        ...state,
        loading: false,
        slides: action.slides,
        currentId: action.slides[0].id // set to first slide
      }
    case 'FETCHING_SLIDES_ERROR':
      return {...state, loading: false, error: action.error}
    default:
      return state
  }
}

const fetchSlides = () => Promise.resolve([
  {id: 'abc'},
  {id: 'def'},
  {id: 'ghi'}
])

function Slideshow () {
  const [state, dispatch] = useReducer(reducer, initialState)
  useEffect(() => {
    dispatch({type: 'FETCHING_SLIDES_REQUEST'})
    fetchSlides()
      .then(slides => dispatch({type: 'FETCHING_SLIDES_SUCCESS', slides}))
      .catch((error) => dispatch({type: 'FETCHING_SLIDES_ERROR', error}))
  }, [])
  const slide = state.slides.find(slide => slide.id === state.currentId)
  console.log(JSON.stringify({currentId: state.currentId, slide}))
  return (
    <button>{slide ? slide.id : null}</button>
  )
}

describe('Slideshow', () => {
  test('slideshow', async () => {
    const {getByText} = render(<Slideshow />)
    flushEffects()
    await waitForElement(() => getByText('abc'))
  })
})

What you did:

I'm building a slideshow component that will eventually auto-play based on a setTimeout. If i call jest.useFakeTimers(), the test fails. If i remove it, it passes. I've tried using rerender, jest.advanctTimersByTime(1), and flushEffects() in various places in conjunction with the previous.

What happened:

image

Reproduction:

You can just copy/paste the above snippet in a project that's using hooks. CodeSandbox doesn't support jest.useFakeTimers().

Problem description:

You can see in the screenshot, that the correct data is being logged so hypothetically it should show up in the dom but alas, it is not.

Suggested solution:

???

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions