Set state when testing functional component with useState() hook

Anna picture Anna · Mar 25, 2019 · Viewed 29.4k times · Source

When I tested class component with enzyme I could do wrapper.setState({}) to set state. How can I do the same now, when I am testing function component with useState() hook?

For example in my component I have:

const [mode, setMode] = useState("my value");

And I want to change mode inside my test

Answer

Moti Azu picture Moti Azu · Mar 25, 2019

When using state from hooks, your test must ignore implementation details like state in order to properly test it. You can still make sure the component passes the correct state into its children.

You can find a great example in this blog post written by Kent C. Dodds.

Here's an excerpt from it with a code example.

Test that relies on state implementation details -

test('setOpenIndex sets the open index state properly', () => {
  const wrapper = mount(<Accordion items={[]} />)
  expect(wrapper.state('openIndex')).toBe(0)
  wrapper.instance().setOpenIndex(1)
  expect(wrapper.state('openIndex')).toBe(1)
})

Test that does not rely on state implementation details -

test('counter increments the count', () => {
  const {container} = render(<Counter />)
  const button = container.firstChild
  expect(button.textContent).toBe('0')
  fireEvent.click(button)
  expect(button.textContent).toBe('1')
})