You can test React components like you write tests for API
React Testing Library is a set of helpers that let you test React components without relying on their implementation details. This approach makes refactoring a breeze and also nudges you towards best practices for accessibility. Although it doesn’t provide a way to “shallowly” render a component without its children, a test runner like Jest lets you do this by mocking.
First we will look into some of the methods which helps in writing the tests using React Testing Library.
React Testing Library Methods for Finding Elements
Most of your React test cases should use methods for finding elements. React Testing Library provides you with several methods to find an element by specific attributes :
getByText()
: find the element by its textContent valuegetByRole()
: by itsrole
attribute valuegetByLabelText()
: by itslabel
attribute valuegetByPlaceholderText()
: by itsplaceholder
attribute valuegetByAltText()
: by itsalt
attribute valuegetByDisplayValue()
: by itsvalue
attribute, usually for<input>
elementsgetByTitle()
: by itstitle
attribute value
And when these methods are not enough, you can use the getByTestId()
method, which allows you to find an element by its data-testid
attribute:
Example :
The user-event
library is companion library for simulating user-browser interaction. Suppose you have a button component to toggle between Light and Dark theme as follows:
import React, { useState } from "react";
function App() {
const [theme, setTheme] = useState("light");
const toggleTheme = () => {
const nextTheme = theme === "light" ? "dark" : "light";
setTheme(nextTheme);
};
return <button onClick={toggleTheme}>
Current theme: {theme}
</button>;
}
export default App;
Next, you create a test that finds the button and simulates a click event by using the userEvent.click()
method. Once the button is clicked, you can assert the test is a success by inspecting whether the button element text contains "dark" or not:
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import App from "./App";
test("Test theme button toggle", () => {
render(<App />);
const buttonEl = screen.getByText(/Current theme/i);
userEvent.click(buttonEl);
expect(buttonEl).toHaveTextContent(/dark/i);
});
And that’s how you can simulate user events with React Testing Library. The user-event
library also has several other methods like dblClick
for double clicking an element and type
for typing into a textbox. You can checkout the documentation for user-event
library for more info.
Explanation for the above test :
The test code above used React Testing Library’s render
method to virtually render the App
component imported from App.js
file and append it to the document.body
node. You can access the rendered HTML through the screen
object.
To see the result of the render()
call, you can use the screen.debug()
method:
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
screen.debug();
});
Then open your terminal and run npm run test
command. You'll see the whole document.body
tree rendered into your console:
<body>
<div>
<div class="App">
<header class="App-header">
<img alt="logo" class="App-logo" src="logo.svg" />
<p>
Edit<code> src/App.js </code>and save to reload.
</p>
<a
class="App-link"
href="https://reactjs.org"
rel="noopener noreferrer"
target="_blank"
>
Learn React
</a>
</header>
</div>
</div>
</body>
Useful links to learn React Testing Library
Sources:
https://reactjs.org/docs/testing.html
https://www.freecodecamp.org/news/react-testing-library-tutorial-javascript-example-code/