Getting Started React Native Testing Library
Tags: reactnative, testing, react, testdev
Published: 2021-01-18 13:49:20

Let's take a look at what we will be testing. Below is the screenshot of the minimal application, which displays the list of users. Each user card is a User component and within each is a Role component rendering the tag based on the user role. There is also a button to select/deselect each user.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/xu8wre1ozbbhc9d31b1a.png)

To make use of the testing library, you need to install it. The react-native starter is pre-configured to make use of jest to run tests. It works for the testing library.

```bash
npm install @testing-library/react-native --save-dev
```

Let's start with the Role component. It is a UI component displaying the user role and changing the tag color based on the Role which gets assigned to the user.

```js
const Role = ({role}) => {
  const backgroundColor = COLORS[role];

  return (
    <View
      style={{
        backgroundColor,
        marginTop: 5,
        paddingVertical: 5,
        paddingHorizontal: 10,
        borderRadius: 15,
        justifyContent: 'center',
      }}>
      <Text style={{fontSize: 10}}>{role}</Text>
    </View>
  );
};
```

To write the unit test for the component, we have to test two pieces of functionality. One correct color gets assigned, and the right text is displayed.

To create an instance of the component, we use the `render` method from the testing library.

```js
const rendered = render(<Role role={'Admin'} />);
```

To check for text we use [`getByText`](https://callstack.github.io/react-native-testing-library/docs/api-queries#bytext) method provided by lib.
```js
const tag = rendered.getByText('Admin');
```

If text exists within your rendered component function will pass the test; else, it will fail. There are other similar methods to be used from the library.
* getByText
* getByPlaceholderText
* getByDisplayValue
* getByTestId and more.

Next, we need to check for the `backgroundColor` for the component. We access the component instance we got above and use it to get the color property and check it. We can do it all in a single test as below.

```js
it(`renders admin correctly`, () => {
  const rendered = render(<Role role={'Admin'} />);
  const tag = rendered.getByText('Admin'); 
  expect(tag.parent.props.style.backgroundColor)
    .toBe(COLORS.Admin);
});
```

Now we come to the User component, which renders user information, displays role tag, and allows the user to select/deselect. We have to check for information getting rendered, button appearance, and click event being dispatched.

Starting by rendering the component, we do it in a similar way we have done above. Then checking if the correct text is present in it.
```js
const isSelected = false;
    const user = {
      name: {
        first: 'Sumit',
        last: 'Arora',
      },
      email: 'sumit@mail.com',
      role: 'Admin',
      picture: {},
    };

    const rendered = render(
      <User isSelected={isSelected} user={user} />,
    );
    rendered.getByText('Sumit Arora');
    rendered.getByText('sumit@mail.com');
    rendered.getByText('Admin');
```

In the above code, we render the User component by using the `render` method from the testing library by providing mock data to it. Then we check if all the expected values are present in the rendered component.

After checking the text, we come to the Button. We will first test its appearance and then functionality. To check UI, we get the instance of Button using the `getByText` method and check its text color and' parent containers `backgroundColor.`

```js
  const button = rendered.getByText('Select');
  expect(button.props.style.color).toBe('#000000');
    
  expect(button.parent.props.style.backgroundColor)
    .toBe('#00b4d8');

```

Last we need to check the click functionality of the Button. For that, we create a mock function and pass it down to the component. We will leverage [`fireEvent`](https://callstack.github.io/react-native-testing-library/docs/api#fireeventeventname) method from the testing library and call the function and check the jest function invocation.

```js
it(`renders admin correctly when not selected`, () => {
  const isSelected = false;
  const user = {
    name: {
      first: 'Sumit',
      last: 'Arora',
    },
    email: 'sumit@mail.com',
    role: 'Admin',
    picture: {},
  };
  const selectUser = jest.fn();

  const rendered = render(
    <User isSelected={isSelected} user={user} select={selectUser} />,
  );
  rendered.getByText('Sumit Arora');
  rendered.getByText('sumit@mail.com');
  rendered.getByText('Admin');

  const button = rendered.getByText('Select');
  expect(button.props.style.color).toBe('#000000');
  expect(button.parent.props.style.backgroundColor)
    .toBe('#00b4d8');

  fireEvent(button, 'onPress');
  expect(selectUser).toHaveBeenCalledWith(false);
});
```

Full Source code can be found here: https://github.com/app-demos/ReactNativeTesting

> Photo by [Shahadat Rahman](https://unsplash.com/@hishahadat)

`Disclaimer: There are other ways to test the similar functionality also. Above is just one of the ways to do so.`