React-testing-library: [bug] fireEvent needs to be wrapped

Created on 21 Aug 2019  路  7Comments  路  Source: testing-library/react-testing-library

  • react-testing-library version: latest
  • react version: 16.9.0
  • node version: n/a
  • npm (or yarn) version: n/a

Relevant code or config:

window.innerWidth = 500
window.innerHeight = 500
fireEvent(window, new Event('resize'))

What you did:

ran tests

What happened:

Received this warning and error:

Warning: It looks like you're using the wrong act() around your test interactions.

Reproduction:

run the code above in one of your tests

Problem description:

See this twitter thread:

Suggested solution:

Kent recommends wrapping fireEvent

Most helpful comment

Not sure about in codesandbox, but, works when using my code local:

useWindowSize.js

import React from 'react'

function useWindowSize() {
  const [size, setSize] = React.useState({
    width: window.innerWidth,
    height: window.innerHeight,
  })
  const handleResize = () =>
    setSize({width: window.innerWidth, height: window.innerHeight})

  React.useLayoutEffect(() => {
    window.addEventListener('resize', handleResize)
    return () => {
      window.removeEventListener('resize', handleResize)
    }
  }, [])

  return size
}

export default useWindowSize

__tests__/useWindowSize.js

import { fireEvent } from '@testing-library/react'
import { renderHook, act } from '@testing-library/react-hooks'
import useWindowSize from '../useWindowSize'

test('should return new size of window', () => {
  const { result } = renderHook(() => useWindowSize())

  expect(result.current.width).toBe(1024)
  expect(result.current.height).toBe(768)

  act(() => {
    // Change the viewport to 500px.
    window.innerWidth = 500
    window.innerHeight = 500

    // Trigger the window resize event.
    // window.dispatchEvent(new Event('resize'))
    fireEvent(window, new Event('resize'))
  })

  // console.log(`result: ${JSON.stringify(result.current, null, 2)}`)
  expect(result.current.width).toBe(500)
  expect(result.current.height).toBe(500)
})

All 7 comments

Whoops, I just realized that we _do_ already wrap fireEvent: https://github.com/testing-library/react-testing-library/blob/c4e51fbbc8895669a5159e5655b7b6d9bc7f8659/src/pure.js#L106-L112

Hmm... We'll have to figure out why this is requiring act...

Hmmm... Does your test run at all? I'm getting an error: https://codesandbox.io/s/react-codesandbox-bq31x

Not sure about in codesandbox, but, works when using my code local:

useWindowSize.js

import React from 'react'

function useWindowSize() {
  const [size, setSize] = React.useState({
    width: window.innerWidth,
    height: window.innerHeight,
  })
  const handleResize = () =>
    setSize({width: window.innerWidth, height: window.innerHeight})

  React.useLayoutEffect(() => {
    window.addEventListener('resize', handleResize)
    return () => {
      window.removeEventListener('resize', handleResize)
    }
  }, [])

  return size
}

export default useWindowSize

__tests__/useWindowSize.js

import { fireEvent } from '@testing-library/react'
import { renderHook, act } from '@testing-library/react-hooks'
import useWindowSize from '../useWindowSize'

test('should return new size of window', () => {
  const { result } = renderHook(() => useWindowSize())

  expect(result.current.width).toBe(1024)
  expect(result.current.height).toBe(768)

  act(() => {
    // Change the viewport to 500px.
    window.innerWidth = 500
    window.innerHeight = 500

    // Trigger the window resize event.
    // window.dispatchEvent(new Event('resize'))
    fireEvent(window, new Event('resize'))
  })

  // console.log(`result: ${JSON.stringify(result.current, null, 2)}`)
  expect(result.current.width).toBe(500)
  expect(result.current.height).toBe(500)
})

When setup on your CodeSandbox: Failed to execute 'dispatchEvent' on 'EventTarget': parameter 1 is not of type 'Event'.

Any idea why? https://codesandbox.io/s/react-codesandbox-g8b2v

ok, locally (no codesandbox), fireEvent does work, but setting up the window.innerWidth does not. I will close the issue, but there is your other reason for needing act.

Works:

  act(() => {
    // Change the viewport to 500px.
    window.innerWidth = 500
    window.innerHeight = 500
  })
  fireEvent(window, new Event('resize'))

Not Working:

  window.innerWidth = 500
  window.innerHeight = 500
  fireEvent(window, new Event('resize'))

Sorry Kent, it is not true. The above does pass the tests, but with the same warning as above. I will let you decide if this is an issue. I spent 2 days on this and have to move on.

Thanks for looking into it @talves!

Was this page helpful?
0 / 5 - 0 ratings