Custom rendering in React Testing Library Done Right

Matan Borenkraout
Nielsen-TLV-Tech-Blog
2 min readApr 12, 2020

This post is also available in my personal site:
https://matan.io/posts/custom-rendering-rtl

Browsing multiple projects, I encountered a recurring pattern when trying to write a custom render for components that use Providers (React-Redux’s Provider, React-Intl’s IntlProvider for example).
This pattern usually looks like this:

renderWithRedux example, it’s a bad practice

This function is nice. It creates a utility that lets us call it whenever we want to test a connected component. The only problem is, it’s limited and causes an inconsistent behavior.
Usually, our app will work with several Providers, not only one, and this solution becomes squeaky when we try to add more Providers to it.
Another thing is that using it will cause inconsistency since we will call renderWithRedux every time instead of calling render as we usually do and we will also import the renderWithRedux from our test-utils file and all the other RTL utils like screen and fireEvent from @testing-library/react.
We will probably get something like this:

Importing from both places creates inconsistency

To fix this, React Testing Library lets us create a custom render function.
I have to be clear. This functionality isn’t new, it’s just not well known or used (in most of the projects I’ve seen lately).
To create a custom render function, we don’t have to work hard.

Full blown custom render function

By doing this, we’ve created a function that uses the Wrapper option of RTL’s render. On top of it all, we also exported all the other functionalities so now we can import our render function and all the other React Testing Library functionality (fireEvent , screen etc.) from the same place.

Let’s take an example of a simple connected, translated, styled date component (This is an imaginary use case 😅):

A test using the custom render we built

We can see that I imported render and screen from our test utils, and this test is actually using all of our Providers: ThemeProvider, React-Redux’s Provider and IntlProvider.

That’s it! I hope I made everything clear.
If you have any questions, feel free to ask.
I’m here and also on twitter.
Thanks for reading!

--

--

Matan Borenkraout
Nielsen-TLV-Tech-Blog

Frontend Engineer | Creating better software, one word at a time | Matan.io