'How do I re-render a component in Jest?

I have a beforeEach() that renders my app:

describe('...', () => {
  beforeEach(() => {
    render(<App />);
  });
  ...
});

I am currently going through a config change in my app. config was previously a boolean value in localStorage and now it has a more appropriate value like prod and dev. My app checks the old boolean values when it first loads and it changes them to their respective non-boolean value - here's the mapping:

true -> prod
false -> dev

I am trying to write tests for this transformation in Jest. The idea behind the first test is to set the localStorage item, re-render the app, and check the the localStorage item has been updated correctly:

it('should show dev config when using old boolean value', () => {
  const toggle = screen.getByTestId('toggle');
  expect(toggle).toBeChecked();
  localStorage.setItem('config', false);

  // re-render app and check localStorage
  render(<App />);
  const toggle2 = screen.getByTestId('toggle');

  expect(toggle2).not.toBeChecked();
  expect(localStorage.getItem('config')).toEqual('dev');
});

However, this test throws an error presumably because the app is now rendered twice instead of once:

TestingLibraryElementError: Found multiple elements by: [data-id="toggle"]

How do I re-render the app so that it isn't duplicated in the test environment?



Solution 1:[1]

You could use the rerender function from react-testing-library : https://testing-library.com/docs/marko-testing-library/api/#rerender

In your test :

import { ..., rerender } from '@testing-library/react';

it('should show dev config when using old boolean value', () => {
  const toggle = screen.getByTestId('toggle');
  expect(toggle).toBeChecked();
  localStorage.setItem('config', false);

  // re-render app and check localStorage
  rerender(<App />);
  const toggle2 = screen.getByTestId('toggle');

  expect(toggle2).not.toBeChecked();
  expect(localStorage.getItem('config')).toEqual('dev');
});

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Florian Motteau