React30-Part25: Simulating user interactions with react-testing-library

Saurabh Mhatre
3 min readOct 31, 2023

--

Title image

Testing user interactions is a crucial aspect of frontend development. It ensures that your components respond correctly to user actions. In this step, we’ll cover simulating clicks and events, testing input and forms, and navigating and routing. Let’s dive in with examples using actual component code.

Simulating Clicks and Events

Simulating user interactions like clicks, mouse events, and keyboard events is essential to validate the behavior of interactive components.

Example Component: ButtonComponent

// ButtonComponent.jsx
import React, { useState } from 'react';

const ButtonComponent = () => {
const [clicked, setClicked] = useState(false);

const handleClick = () => {
setClicked(true);
};

return (
<button onClick={handleClick}>
{clicked ? 'Clicked!' : 'Click Me'}
</button>
);
};

export default ButtonComponent;

Writing the Test:

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

test('clicking the button changes its text', () => {
// Render the component
const { getByText } = render(<ButtonComponent />);

// Find the button element
const buttonElement = getByText(/Click Me/i);

// Simulate a click event
fireEvent.click(buttonElement);

// Assert that the button text changes
expect(buttonElement).toHaveTextContent('Clicked!');
});

In this example, we have a ButtonComponent that changes its text when clicked. The test simulates a click event on the button and verifies if the text changes accordingly.

Input and Form Testing

Testing user input is crucial for components that involve forms, inputs, and validation.

Example Component: InputForm

// InputForm.jsx
import React, { useState } from 'react';

const InputForm = () => {
const [inputValue, setInputValue] = useState('');

const handleChange = (e) => {
setInputValue(e.target.value);
};

return (
<div>
<input
type="text"
value={inputValue}
onChange={handleChange}
/>
<p>Value: {inputValue}</p>
</div>
);
};

export default InputForm;

Writing the Test:

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

test('typing in the input updates the value', () => {
// Render the component
const { getByLabelText, getByText } = render(<InputForm />);

// Find the input element by its label text
const inputElement = getByLabelText(/Value/i);

// Simulate typing in the input
fireEvent.change(inputElement, { target: { value: 'Hello' } });

// Find the paragraph element displaying the value
const valueElement = getByText(/Value:/i);

// Assert that the value is updated
expect(valueElement).toHaveTextContent('Value: Hello');
});

In this example, we have an InputForm component with an input field. The test simulates typing in the input and verifies if the displayed value updates accordingly.

Navigating and Routing

Testing navigation and routing ensures that components behave correctly when users navigate through the application.

Example Component: NavigationComponent

// NavigationComponent.jsx
import React from "react";
import { Link, BrowserRouter as Router, Route, Switch } from "react-router-dom";

const Home = () => <div>Main Page</div>;
const About = () => <div>About Page</div>;

const NavigationComponent = () => {
return (
<Router>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
<Switch>
<Route path="/about" component={About} />
<Route path="/" component={Home} />
</Switch>
</Router>
);
};

export default NavigationComponent;

Writing the Test:

// NavigationComponent.test.jsx
import React from "react";
import { render, fireEvent } from "@testing-library/react";
import { MemoryRouter } from "react-router-dom";
import NavigationComponent from "./NavigationComponent";

test("navigating between pages", () => {
// Render the component with MemoryRouter
const { getByText } = render(
<MemoryRouter initialEntries={["/"]}>
<NavigationComponent />
</MemoryRouter>
);

// Find the navigation links
const homeLink = getByText(/Home/i);
const aboutLink = getByText(/About/i);

// Simulate clicking on the About link
fireEvent.click(aboutLink);

// Assert that the About page is rendered
expect(getByText(/About Page/i)).toBeInTheDocument();

// Simulate clicking on the Home link
fireEvent.click(homeLink);

// Assert that the Home page is rendered
expect(getByText(/Main Page/i)).toBeInTheDocument();
});

In this example, we have a NavigationComponent that provides navigation links to the Home and About pages. The test simulates clicking on these links and verifies if the corresponding pages are rendered.

Live code can be found here:-

Codesandbox

Conclusion

These examples demonstrate how to test user interactions in React components using React Testing Library. By simulating events and user input, you can ensure that your components respond correctly to user actions. This level of testing is essential for building robust and reliable frontend applications. Have a nice day ahead!

You can check out more content on my Youtube channel:-
SaurabhNative-Youtube

Next part in the series we’ll cover how to mock API calls

React30-Part26

--

--

Saurabh Mhatre

Senior Frontend Developer with 9+ years industry experience. Content creator on Youtube and Medium. LinkedIn/Twitter/Instagram: @SaurabhNative