0

I'm using @testing-library/react for testing an app with legacy code. Basically, each time I click a button is shown a message component. The message is the legacy code. This legacy component injects HTML in the DOM.

When a Test my application, I realized that the code injected by legacy code is not clear between the tests.

Repos.js

import React, { useState } from 'react';

function showMessage() {
  const message = document.createElement('div');
  message.innerHTML = '<h1>Successfully saved!</h1>';
  document.body.appendChild(message);
}

export default function Repo() {
  const [repos, setRepos] = useState([]);

  function handleOnClick() {
    setRepos([
      { name: 'Repo 1' },
      { name: 'Repo 2' },
    ]);
    showMessage();
  }

  return (
    <nav>
      <button onClick={handleOnClick}>Show repos</button>
      <ul>
        {repos.map(repo => <li data-testid={repo.name} key={repo.name}>{repo.name}</li>)}
      </ul>
    </nav>
  )
}

Repos.test.js

import React from 'react';
import Repos from './Repos';
import { render, cleanup, fireEvent } from '@testing-library/react';


describe('Repos', () => {
  describe('when clicking the button', () => {
    beforeEach(() => cleanup());

    it('should updates repos collection', () => {
      const { container, getByText, getByTestId } = render(<Repos />)

      fireEvent.click(getByText('Show repos'));

      expect(getByTestId('Repo 1')).toBeTruthy();
      console.log(container.innerHTML);
    });

    it('should show the success message component', () => {
      const { container, getByText } = render(<Repos />)

      fireEvent.click(getByText('Show repos'));


      expect(getByText('Successfully saved!')).toBeTruthy();
      console.log(container.innerHTML);
    })
  })
})

enter image description here

skyboyer
  • 15,149
  • 4
  • 41
  • 56
Pablo Darde
  • 3,855
  • 6
  • 29
  • 47

1 Answers1

2

You may(and need) to clean document before each test:

beforeEach(() => {
  document.body.innerHTML = "";
});

If by a chance your showMessage is in separate file, I'd suggest mocking it in your tests. This way you would also avoid testing its internals everywhere(except tests focused on showMessage itself for sure)

skyboyer
  • 15,149
  • 4
  • 41
  • 56