Edit (2020): I would recommend switching over to react-testing-library, and changing your testing approach to test how your component changes with state rather than that state changed. While this approach works, it is not the ideal solution to the problem. I originally came up with this solution because I started React work using class components and being able to use the enzyme helpers to directly test my values of state against what I expected. With hooks, the testing approach has changed and that is no longer ideal. We should be testing our full component and how the component responds to the state change, not that state has changed.
With the introduction of React Hooks, testing our components state changes is not as straight forward as it used to be. However, it is still possible to test these state changes directly. It just requires a little mocking. 🤠
Previously, if you used a React Class Component, you could simply read and manipulate the component state from the shallow object enzyme provides us through shallow rendering.
Implementations I've found around this subject before talked about testing the repercussions of changing state. For example, state updates and we test that the displayed count value is what we expect, or we test that a function is called with the correct parameter from state, etc.
Which, I would say is a completely valid way to test your state change. However, it feels like it goes against the isolation we should consider when unit testing.
If I'm testing my onClick event, all I really care about for my test is that is calls setCount with whatever variable it should. We trust that React works correctly; so, my test shouldn't rely on useState updating my state variable and re-rendering my component for my unit test.
So, why don't we mock it?
With this implementation, we are mocking React.useState to return an Array with the initial value passed to the method and a jest mock function. This will set the states setter to our mock function and allow us to test that it was called with the expected value to set state to.
Pretty neat! Now there is no need for us to dig through props to check that our state gets set correctly. 👌