Skip to main content

Testing React loader with React Testing Library

 I have came across this situation so many times where I need to write a unit test for a component pattern I have developed so many times that I can write the code with my eyes closed.

BUT what about unit testing!

That's something my mind thought is the best candidate to get rid of in order to store more cat memes.

Even when these patterns are used almost everywhere and we write the tests for each one of them (I hope you do) but still we (it can't be just me) tend to forget them and get even more confused with those pesky `act` warnings.

So I decided to curate a recipe book for some common unit tests which I come across and might be useful for future me. Happy to share the github repo and also would love to see if anyone has more such common unit testing patterns which they can add or suggest.

https://github.com/Charchit26/react-testing-library-recipes

Now, let's talk about the one I have coded a dozen times and still take half an hour to struggle with its unit tests - Loader icon while an API call is being made.

This specific example can be found here.

Here I need to render a Loading icon/text for the time being an API call is being made and once it resolves then replace the icon with something else.

Let's start with out React component under test - LoaderWithAPICall (I know such a thoughtful name!)

import React, {useEffect, useState} from "react";
import callAnApi from "./api";
export default function LoaderWithAPICall() {
const [data, setData] = useState();
const [loading, setLoader] = useState(true);
useEffect(() => {
async function fetchData() {
setLoader(true);
const response = await callAnApi()
setData(response.data)
setLoader(false);
}
fetchData().then(() => {});
}, []);
return (
<>
{loading ? "Loading..." : `Data obtained from API call: ${data}`}
</>)
}
Now we start with out first test - it should show the loading icon initially.

I am mocking the API call upfront as I know it will be called on every render and if you have got an expensive or external API call hooked up, you don't really want to keep calling it in the tests.

import {render, screen, waitFor} from "@testing-library/react";
import LoaderWithAPICall from "./LoaderWithAPICall";
import callAnApi from "./api";
jest.mock('./api', () => (
jest.fn()
))
describe('<LoaderWithAPICall />', () => {
beforeEach(() => {
callAnApi.mockResolvedValue({data: "testData"})
})
it('renders the loader initially', async () => {
render(<LoaderWithAPICall/>)
await waitFor(() => expect(screen.getByText(/Loading.../i)).toBeInTheDocument());
})
});

This will test if the `Loading...` text is available as soon as we render the component.

Here, we had to add a ``waitFor` to get rid of the `act` warnings.

If you're being troubled by the ghosts of act again and again you might need a dose of this beautiful blogpost - https://davidwcai.medium.com/react-testing-library-and-the-not-wrapped-in-act-errors-491a5629193b
Thanks David!

Now, let's go a step further and test if the API call was made and if it was then does it change the text on the screen.

it('renders the data after promise resolves', async () => {
render(<LoaderWithAPICall/>)
expect(callAnApi).toHaveBeenCalledTimes(1);
await waitFor(() => {
expect(screen.getByText("Data obtained from API call: testData")).toBeInTheDocument();
})
});

Pretty simple, right?

This should be able to give you a good idea to start with such common unit testing patterns.
And again, if you can think of something else which you see in react tests very usually please fele free to raise a pull request.

Let's end with a programming meme ;P



Comments

Popular posts from this blog

Send Anonymous Mails!

Ever thought of a mischievous act like sending a mail with  a fake identity or using someone else's identity?? Sure, if you have that naughty prankster hidden in you! So there are ACTUALLY two common sites which may help you in such pranks.. They are... 1: http://www.sendanonymousemail.net/ Its got a pretty easy and user-friendly interface which makes it so special.. 2:   https://emkei.cz/ It can be considered as the advanced version for sending fake mails.. Its got a good variety of options for "geeks" as well as an html editor for cutomizing the mails! But Do Remember that  these tools would let you   send anonymous emails   free of cost   and let you be  hidden   at the same time, but they Do store your IP addresses, just in case your anonymous email indulges in illegal activities! So, Do NOT even try to send scary threats or spam like messages because you may get caught very easily and can be charged with fr...

Connect 2 Computers using USB to USB cable

A very easy way to connect two PCs is to use a USB-USB cable. By connecting two PCs with a cable like this, you can transfer files from one PC to another, and even build a small network and share your Internet connection with a second PC. The first thing you should be aware of is that there are several different kinds of USB-USB cables on the market. The one used to connect two PCs is called “bridged” (or “USB networking cable”), because it has a small electronic circuit in the middle allowing the two PCs to talk to each other. Cable without a bridge connector are called A/A USB cables and cannot be used to connect two PCs. In fact, if you use an A/A USB cable, you can burn the USB ports of your computers or even their power supplies . So, these A/A USB cables are completely useless. A/B USB cables are used to connect your computer to peripherals such as printers and scanners, so they also won’t meet your needs. As for speed, the bridge chip can be USB 2.0 (480 Mbps). The stand...