JavaScript in Plain English

New JavaScript and Web Development content every day. Follow to join our 3.5M+ monthly readers.

Follow publication

Get Started with React Testing Library and Jest

Ankit Saxena
JavaScript in Plain English
5 min readJan 1, 2022

--

Photo by James Harrison on Unsplash

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:

  1. 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:

  1. It’s slow
  2. 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:

  1. Setting up a server i.e listens for any requests made to the provided API.
  2. Intercepts them, and
  3. 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.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Published in JavaScript in Plain English

New JavaScript and Web Development content every day. Follow to join our 3.5M+ monthly readers.

No responses yet

Write a response