Subscribe

Changing the default testing container

✍️

How to define the wrapping container for a component in Testing Library

17 Apr, 2022 Β· 3 min read

By default testing, the library will append your render to the body, for which it first will apply a div.

The format will result in something like this:

<body>
  <div>
    <YourComponent />
  </div>
</body>

However, you might want to test for other scenarios in some cases.

I'll write two down that I have dealt with so far:

  • Custom component wrappers (custom elements)
  • HTML based emails (wrapped in table layout)

In those cases, we want to define another type of wrapper.

Defining a new wrapping container

For example, let's take the previous article. What if we want to render the App in a table?

This is the current test setup:

const renderComponent = ({ username }) => {
  return render(
    <UserContextProvider user={username}>
      <App />
    </UserContextProvider>
  );
};

it('should show the login option', async () => {
  renderComponent('');
  expect(screen.queryByText('Please login')).toBeInTheDocument();
});

Nothing strange so far, when debugging this code it would give us a HTML output like:

<body>
  <div>Please login</div>
</body>

Now let's see how we can add a Table. For this to work, we have to pass an optional parameter to the render function called container.

const renderComponent = ({ username }) => {
  const table = document.createElement('table');
  return render(
    <UserContextProvider user={username}>
      <App />
    </UserContextProvider>,
    {
      container: document.body.appendChild(table),
    }
  );
};

Running the above code would throw us an error, as we cannot directly append text nodes to a table.

But now, imagine the component we are testing is a TableBody component. It would make sense to test that inside a table.

The output would become:

<table>
  <TableBodyComponent />
</table>

Testing custom elements

In my case, I recently had to test a custom component wrapper. This was mainly due to injecting something specifically in the shadow DOM.

The process for this is very similar. However, we define our custom element as the new tag.

const renderComponent = ({ username }) => {
  const customTag = document.createElement('custom-tag');

  return render(
    <UserContextProvider user={username}>
      <App />
    </UserContextProvider>,
    {
      container: document.body.appendChild(customTag),
    }
  );
};

The output will now be:

<custom-tag> Please login </custom-tag>

Be aware most components won't need a different container, but there are these exceptions where this can make your life easier to define one.

Thank you for reading, and let's connect!

Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter

Spread the knowledge with fellow developers on Twitter
Tweet this tip
Powered by Webmentions - Learn more

Read next πŸ“–

Testing library asFragment tests

18 Apr, 2022 Β· 2 min read

Testing library asFragment tests

Testing library and React context

16 Apr, 2022 Β· 4 min read

Testing library and React context

Join 1828 devs and subscribe to my newsletter