DEV Community

Discussion on: Struggle with React and unit tests

Collapse
 
sargalias profile image
Spyros Argalias

According to the documentation, the end result is that the <body> element gets a class.

If using React testing library and Jest, here's the test I would write:

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

test('', () => {
  const { getByTestId } = render(<ThemeToggle/>);
  const themeToggleCheckbox = getByTestId('themeToggleCheckbox'); // the checkbox needs data-testid="themeToggleCheckbox" for this

  // check first click changes class to "dark"
  fireEvent.click(themeToggleCheckbox);
  expect(document.body).toHaveClass('dark');
  expect(document.body).not.toHaveClass('light');

  // check second click changes class to "light"
  fireEvent.click(themeToggleCheckbox);
  expect(document.body).toHaveClass('light');
  expect(document.body).not.toHaveClass('dark');
});
Enter fullscreen mode Exit fullscreen mode

Notes:

The fireEvent.click feels very weird to me. In my opinion fireEvent.input is much more appropriate. However it doesn't work. It's just an implementation detail we have to accept for this test.

The reasons we use fireEvent are because: 1. To simulate an end to end test as much as we can (the user would click the checkbox, so we match this as much as we can by firing a click event). 2. Because we actually have to when using React testing library.

Collapse
 
nans profile image
Nans Dumortier

Thank you for your help !
My linter was complaining when I was using document, so I decided to query the container of the toggle.
Then I had to mock window.__setPreferredTheme which is used by the gatsby plugin, and everything worked.
Thanks again for your help :)