Any time your test interacts with a React component in a way that results in a state update, you need to make sure you wrap that interaction in an act
function call, otherwise you'll get the "not wrapped in act(...)" warning.
In this lesson you'll learn how you can use act
with @testing-library/react-hooks
to avoid potential bugs in your custom React hooks.
This is based on my blog post: Fix the "not wrapped in act(...)" warning
Kend Dodds: [0:00] Here we have a simple custom hook called useCount. It's managing a count state. It has an increment and decrement function to increment and decrement the count value. Then it's returning an object with the count increment and decrement.
[0:15] To test this, we're using React hooks testing library and we're using the renderHook function from that. Then with renderHook, we have this function that we provide that returns the value from using our hook useCount.
[0:28] That gets us back an object from which we can pluck the result. Then we can say result current count to be zero. Then we call increment, and now we expect it to be one. Then decrement and expect it to be zero again.
[0:41] Now if we run our test, we're going to get this act warning right here, an update to our TestHook which is actually being rendered by testing library React hooks inside a test was not wrapped in act. Whenever you get a warning like this, the thing you need to ask yourself is, what interaction am I doing in my test that's triggering a state update?
[1:01] As we can see here, we've got increment and decrement. Those are both calling setCount which will trigger a state update. Those are the things that we need to take into consideration with this particular warning. We're calling those each once, and each of those needs to be wrapped in act.
[1:18] Now, the testing library React hooks module uses React test to render. We need to use the act function from React test render. Lucky for us, testing library React hooks re-exports that function so we can pull act directly from that same import.
[1:33] Then we wrap each one of these in an act function call to indicate to React that these function calls are going to trigger state updates. After everything that happens in this function, we want the state changes to be flashed and the effects to be called.
[1:47] If we save that, now we have a passing test without the warning. In review, anytime you're testing a custom hook like useCount here and you have any interaction that results in a state update, you need to wrap that interaction in an act function call.