Why should you use react testing library in your next project

Unit testing is one of the main aspect when developing a project, irrespective of whether its React or Angular. There are many testing libraries in React, popular ones among them are React testing library and Enzyme. React testing library is different from other test libraries out there.

Is React testing library something new?

React testing library does not offer radical or invent new apis to test react app. On the contrary, it offers less functionality than an Enzyme library. Then why would you use a library that offers lesser features than other library? Its because React testing library forces you to focus on certain aspect of testing

React testing library forces you to not test the implementation of your React component. Rather, you test the component the way it is going to be used in the app.
If you have a list component, then only thing you would be concerned about from usage perspective is that you are going to pass some props to it, and you will get a list view. So you are going to test your list component in the same way. React testing library does not provide methods to test the internals of the component, that is, state or props.

So in react testing library, you will be passing some props to the component, and testing its output. Thats what it is.

You will also need to learn how to mock the apis, mock the child components, mock the library components and few other tricks, but in the end, you are going to test the render output of your component.

What you cannot do in React testing library

... that you can do in other libraries

You cannot access the instance method of your component like you do in enzyme.

const wrapper = shallow(<List/>);
wrapper.instance().testMethod()

You cannot access the state of the component like you do in enzyme

const wrapper = shallow(<List/>);
wrapper.state('name');

You cannot access the props of the component like you do in enzyme

const wrapper = shallow(<List/>);
wrapper.prop('name');

You cannot find the child components like you do in enzyme

const wrapper = shallow(<List/>);
wrapper.find(ListTitle);

Why is it useful

Till now, we saw what react testing library does not provide. Lets see what it *does* provide

Powerful dom matchers

React testing library provides a number of DOM matchers which you can use to assert conditions. You can get/query and element and have assertions based on it.

  • ByLabelText find by label or aria-label text content
    • getByLabelText
    • queryByLabelText
    • getAllByLabelText
    • queryAllByLabelText
    • findByLabelText
    • findAllByLabelText
  • ByPlaceholderText find by input placeholder value
    • getByPlaceholderText
    • queryByPlaceholderText
    • getAllByPlaceholderText
    • queryAllByPlaceholderText
    • findByPlaceholderText
    • findAllByPlaceholderText
  • ByText find by element text content
    • getByText
    • queryByText
    • getAllByText
    • queryAllByText
    • findByText
    • findAllByText
  • ByDisplayValue find by form element current value
    • getByDisplayValue
    • queryByDisplayValue
    • getAllByDisplayValue
    • queryAllByDisplayValue
    • findByDisplayValue
    • findAllByDisplayValue
  • ByAltText find by img alt attribute
    • getByAltText
    • queryByAltText
    • getAllByAltText
    • queryAllByAltText
    • findByAltText
    • findAllByAltText
  • ByTitle find by title attribute or svg title tag
    • getByTitle
    • queryByTitle
    • getAllByTitle
    • queryAllByTitle
    • findByTitle
    • findAllByTitle
  • ByRole find by aria role
    • getByRole
    • queryByRole
    • getAllByRole
    • queryAllByRole
    • findByRole
    • findAllByRole
  • ByTestId find by data-testid attribute
    • getByTestId
    • queryByTestId
    • getAllByTestId
    • queryAllByTestId
    • findByTestId
    • findAllByTestId

For example, if you want to test that your component contains some text, then you can use

const wrapper = render(<List>);
// assuming that you have added testid of title to each of the list item
const titles = wrapper.queryAllByTestId('title');
// you will get an array of values, which you can then assert.
expect(titles).toEqual(['a','b','c']);

Create react app uses React testing library

The official react app boilerplate provided by the React uses the React testing library as default. So this shows how much the adoption of React testing library has increased.

Ease of use

In enzyme, you would need to set it up using an adapter.

import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

Enzyme.configure({ adapter: new Adapter() });

But in React Testing library, you can just import the component and get started with it

No forceUpdate() or forcing the re-render of component

In Enzyme, you have the forceUpdate method to re-render the component. If you are spying on some arrow function inside the component (arrow functions inside component is wrong), then you would have to forceUpdate the component.

In React Testing Library, you do not have any such methods. Instead, it tests only using the DOM.

Conclusion

I think the above points would nudge you to conside using React testing library in your next project!