Get Started with React Testing Library and Jest
An introduction to Jest and React Testing Library for beginners.
React testing library has become the most popular option to write test cases for React applications. These test cases resemble how a user would use your application. If you are using the latest version of the create-react-app tool then you already have Jest and Testing Library already installed for you.

Before diving into the code, let’s get a quick recap of the basics of Jest.
const expected = true;
const actual = false;
describe("simple jest test", () => {
test("it works", () => {
expect(actual).toBe(expected);
});
});
The above code is an example of a simple Jest test. It contains the following:
describe
breaks our test suite into components.
2. test
function is a test case.
3. expect
function is used every time you want to test a value.
Now let’s look into the react code.

Full Source code: Github Repo Link.
Below is a simple todo app built with react and typescript. All it does is that it takes some text as an input and on pressing enter, it adds the entered text to the list. Next, we will be writing test cases for this application.
1. Basic Test
First, let’s test the basic rendering functionality of our react app. For example, if the component or element is properly rendering on the screen or not.
import Todo from './Todo';it('Renders without crashing', () => {
render(<Todo />);
const linkElement = screen.getByText(/Todo App/i);
expect(linkElement).toBeInTheDocument();
});
Here we are importing our <Todo /> component and virtually renders it using the render() function. We will be using queries to get the DOM element we want. Queries are used to find elements on the page (more about Queries from RTL documentation).
We are using the getByText() query provided by RTL. It will give us all the elements that have a text node with textContent matching the given TextMatch (i.e — “Todo App”).
Jest provides the .toBeInTheDocument() matcher, which can be used to assert that an element is in the body of the document, or not.

Tip: we can use screen.debug() to see the current HTML output of components.
2. Testing Events
Now we will check how to test for events. e.g., onChange, onClick, etc.
it("When the Enter button is pressed, it creates a new todo item", () => {
const { getByTestId, getByText } = render(<Todo />);
const event = { target: { value: "test val" } };
fireEvent.change(getByTestId("todo-input"), event);
expect(getByTestId("todo-input")).toHaveValue("test val");
fireEvent.submit(getByTestId("add"));
expect(getByText("test val")).toBeInTheDocument();
});
In the above code, first, we are getting the input by getByTestId(). It’s another way to get an element from the DOM tree having a particular data-testid attribute.(More about getByTestId from RTL documentation).
We are using the fireEvent property provided by RTL to test for events. The second argument (i.e eventProperties) passed to fireEvent is the property that will be assigned to the node which is receiving the event. In other words, the value the element should have when triggering the event. (More about fireEvent from RTL documentation).
const { getByTestId, getByText } = render(<Todo />);
const event = { target: { value: "test val" } };
fireEvent.change(getByTestId("todo-input"), event);
Once the event is fired then we check the DOM to see whether the input has the same value that we passed to fireEvent (in the second argument).
expect(getByTestId("todo-input")).toHaveValue("test val");
Then, we did the same thing for the form submit event and then check whether the entered value in the input box is rendered in the list or not.
fireEvent.submit(getByTestId("add"));
expect(getByText("test val")).toBeInTheDocument();
Note: Another way to test events using RTL is through user-event. (More about user-event from RTL documentation)
3. Bonus: Testing API’s
Another important part of any react application is the APIs we are using. To test the working of these APIs, we’ll mock service workers. It is a simple and efficient way of mocking axios
and fetch
in testing.
What we have below is a simple JavaScript function that will make an API call (Animechan API Link) using axios and return us a random anime name.
import axios from 'axios';const fetchData = () => {
return axios.get('https://animechan.vercel.app/api/random')
.then(res => {
return res.data.anime
})
.catch(err => {
console.log(err)
})
};export default fetchData;11
Here we don’t wanna make actual API requests mainly for the following reasons:
- It’s slow
- It’s unpredictable (the response returned from the API may be different for each request)
So what we actually do is we create a mock server as shown in the below code:
The first few things to import to this test file are {rest} from ‘msw’
and {setupServer} from ‘msw/node’
. We then create a server
variable and set it equal to the setupServer
function. Essentially what setupServer
is doing is:
- Setting up a server i.e listens for any requests made to the provided API.
- Intercepts them, and
- Handles what should be the response.
Here beforeAll() and afterAll() are used to run some particular code (in this case start and close the server) before and after each test run.
Now we can simply use “await fetchData()” to call our API and use expect() to check if the server returns the expected value or not. The real API server may return any random anime name. However, our Mock Service Worker intercepts the request and returns ‘naruto’
in the response, therefore our test will pass!

Full Source code: Github Repo Link.
Video Explanation:
More content at plainenglish.io. Sign up for our free weekly newsletter. Get exclusive access to writing opportunities and advice in our community Discord.