Ben Brostoff

About Posts Book Recos Privacy Email GitHub

11 Aug 2019
React's act

One challenge of writing React tests is knowing where you are in the component lifecycle. Is the component mounted? In the middle of a state update? Has it received props? Answering these questions determines what the tester should assert. Through a colleague at work, I recently found React 16.9 includes an act function that can take an async callback.

act itself, however - which stands for the Arrange-Act-Assert testing pattern existed far before 16.9, and allows you to guarantee all state updates have completed before making assertions on a component. From the docs:

When writing UI tests, tasks like rendering, user events, or data fetching can be considered as “units” of interaction with a user interface. React provides a helper called act() that makes sure all updates related to these “units” have been processed and applied to the DOM before you make any assertions…

I recommend the aforementioned testing recipes page for a full walkthrough of act examples as well as Sunil Pai’s examples - Sunil originally authored the PR that acted async act. For this blog post, I want to walk through a simple example that will show the potential value of this testing utility.

Note - all examples below can be found in this CodeSandbox

Let’s start with a sync act. Consider a component with just a useEffect call that sets a value on the component:

The difference between using act and not using act is the test waiting on the callback inside useEffect:

async act - again, newly released in React 16.9 - allows you to wait on promises to resolve and state updates to complete.

Here’s what an async component might look like…

…and the differences between sync and async act.

Importantly, enzyme and react-testing-library are already pulling act into their API and have means of accessing it (or should have in the future), so if you’re using either library, the above boilerplate isn’t necessary. That said, I found it useful to go through this exercise to get a sense of how act works.

I’m extremely excited React offers this utility - it’s extremely useful in fixing things like intermittently failing tests that rely on promises resolving in some fixed amount of time (which hopefully never existed in your test suite anyways). React testing forces you to understand the lifecycle of your components and how they handle state. act is a great way to enhance that understanding.


About Posts Book Recos Privacy Email GitHub