Testing events with react testing library

In this post we are going to learn how to test (unit) events in a react application with react-testing-library.

For this, we will use the fireEvent module.

Lets see our first example, we will test onChange event for an input field.

// app.js

const [name, setName] = useState('');
<input type="text" value={name} onChange={e => setName(e.target.value)} data-testid="name" />
// app.test.js

import { render, cleanup, screen, fireEvent } from "@testing-library/react";
import App from './App';

afterEach(cleanup);

describe("App component testing", () => {
  it("should be able to type name input field", () => {
    const { getByTestId } = render (<App />);

    fireEvent.change(getByTestId("name"), { target: { value: "Muhammad Lahin" } });
    expect(getByTestId("name").value).toBe("Muhammad Lahin");
  })
})

The render method returns a property getByTestId with that we will get the reference of a DOM element, then we write fireEvent.change() it expects the first parameter should be the reference of the DOM element that we are going to test and the second parameter is actual target value since we are testing an input field. After that we used expect and told the value of that input field should be “Muhammad Lahin”. This way we are able to test input field can take value or not. Now type npm run test to find the test result,

We can see out test passed.

Lets add a new button called submit if user clicks this button the value of input field name should be an empty string.

<input type="text" value={name} onChange={e => setName(e.target.value)} data-testid="name" />
<button onClick={() => setName('')}>Submit</button>

Now lets write test for this,

describe("App component testing", () => {
  it("input field name should be empty after clicking the submit button", () => {
    const { getByTestId } = render (<App />);
    const nameInputElement = getByTestId("name");
    const buttonElement = screen.getByRole("button", {
name: /submit/i
});
    fireEvent.click(buttonElement);
    expect(nameInputElement.value).toBe("");
  }) 
})

Lets add a new test when clicking the Disable button the input field should be disabled,

const [name, setName] = useState('')
const [isDisable, setIsDisable] = useState(false)

<input type="text" value={name} onChange={e => setName(e.target.value)} data-testid="name" disabled={isDisable} />
<button onClick={() => setIsDisable(true)}>Disable</button>
it("input field should be disable after clicking the disable button", () => {
  const { getByTestId } = render (<App />);
  const nameInputElement = getByTestId("name");
  const buttonElement = screen.getByRole("button", { name: /disable/i });
  fireEvent.click(buttonElement);
  expect(nameInputElement.disabled).toBeTruthy();
})

And the test result is,

If you want to learn more check out their official documentation https://testing-library.com/docs/.

Leave a Reply

Your email address will not be published. Required fields are marked *