How to test React components in TypeScript

Testing React components plays a pivotal role in application development because it helps ensure the individual components and the application work as intended and catches bugs before production.

While unit testing and integration testing are possible in React, we’ll discuss only unit testing in this Answer. There are a few recommended tools for testing components in React, such as Jest and React Testing Library. Jest provides more control over the execution and complexity of tests, whereas React Testing Library is more user-friendly and abstracts the test implementation details away from the user. We’ll be using the React Testing Library for this Answer.

Basic component testing

In the first example, let’s render a basic React component using TypeScript to get started and test if it displays the correct text content. The following example has a Hello.tsx component that renders a name. There’s also a Hello.test.tsx test file that checks the output of the Hello.tsx component. Click the “Run” button to start the test.

import React from 'react';
import { render, screen } from '@testing-library/react';
import {Hello} from "./Hello"

test('renders a name', () => {
  render(<Hello name="Mike"/>);
  const linkElement = screen.getByText(/Hello Mike/i);
  expect(linkElement).toBeInTheDocument();
});
An example of basic component testing

Code explanation

Hello.tsx

  • Line 3: We create the Hello component that takes name as prop.

  • Line 5: We render name with the string "Hello" prepended to it.

Hello.test.tsx

  • Line 2: We import the render method and the screen object from the React Testing Library. The render method is used to render components. The screen object queries and interacts with the rendered components during testing.

  • Line 5: We define our test function and pass a test description as an argument to identify the test. The second argument is the callback function that contains the testing logic.

  • Line 6: We call the render function to render the Hello component with name set to Mike provided as the prop.

  • Line 7: Then, we use the getByText method to match any DOMDocument Object Model element with the text content provided as an argument. If our Hello component is rendered correctly, it should display the text, Hello Mike, and the getByText method will extract the DOM element that contains this text content.

  • Line 8: The expect method takes the DOM element as an argument, and the toBeInTheDocument() method is called to check if the DOM element exists in the rendered output.

Event handling testing

In the second example, let’s render a form with a username input field and a login button. After entering the username and clicking the login button, the screen should display the text Login Successful. We’ll test this by creating a Login.tsx component that renders the form and a Login.test.tsx test file that tests the functionality of our component. Click the “Run” button to start the test.

import React from 'react';
import { render, screen } from '@testing-library/react';
import {Hello} from "./Hello"

test('renders a name', () => {
  render(<Hello name="Mike"/>);
  const linkElement = screen.getByText(/Hello Mike/i);
  expect(linkElement).toBeInTheDocument();
});
An example of event handling testing

Code explanation

Login.tsx

  • Line 5: We create the isLoggedIn state variable to check if the user has correctly submitted the form.

  • Lines 7–9: We create the handleLogin event handler that toggles the isLoggedIn state to true when the form is submitted.

  • Line 13: We use conditional rendering to display the form when the isLoggedIn state is false and display the text Login Successful when the isLoggedIn state is true.

  • Line 15: We create an input field where the user will enter their username.

  • Line 16: We create a button and register the handleLogin method as the onClick event handler that triggers when the user clicks on it.

  • Lines 18–19: We set the screen to display the Login Successful message when the isLoggedIn state is false.

Login.test.tx

  • Line 3: Along with the render and screen methods, we also import the fireEvent object that’s used to simulate user interactions with elements in our tests, such as clicking buttons, typing into input fields, or submitting forms.

  • Lines 6–7: We use the describe method to create a test suite to group related test cases. It takes the name of the test suite as the first argument, and the second argument is the callback function that contains the individual test cases within that test suite. We use the it method to make individual test cases. It takes the name of the test case as the first argument and a callback function with the testing logic as the second argument.

  • Line 9: We render the Login component using the render method.

  • Line 13: We use the getByPlaceholderText method to extract the username input element using its placeholder text.

  • Line 14: We use the change method of the fireEvent object to enter a username into the input field. Its first argument is the username input element, whereas the second argument contains the value to be entered in the element.

  • Line 17: We use the getByText method to extract the Login button element. The method takes as an argument the text content of a DOM element to search for.

  • Line 18: We use the click method to simulate clicking the Login button.

  • Line 21: After submitting the form, we use the getByText method to extract the DOM element that contains the text Login Successful.

  • Line 22: Finally, we call the expect method that takes the DOM element as an argument, and call the toBeInTheDocument method to check if the DOM element exists in the rendered output.

Copyright ©2024 Educative, Inc. All rights reserved