React-Testing-Library (RTL) vs Enzyme

manish kumar
Xebia Engineering Blog
3 min readOct 10, 2019
Photo by Louis Reed on Unsplash

If you would have asked me a couple of weeks before about the go-to testing library to test ReactJs application, I would have answered Jest and Enzyme but recently I started working on React Hooks and was trying to test it using Enzyme but I found it is still not supporting React Hooks completely. Here is the open issue on GitHub

Why React-testing-library

I started looking for another testing library which is having better support for hooks and I found React-testing-library by Kent C. Dodds. This is even recommended by React team in their official documentation. So, I thought to give it a try.

Benefits of using React-testing-library

While working with React-testing-library you need to re-think your test cases. It enforces us to write test cases the way the user will interact with the application.

  1. No need to set up or initialize. With Enzyme you need to set up an adaptor to make it working with React 16 but with React-testing-library there is no need to do it.
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

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

2. No Shallow Rendering

It doesn’t have shallow rendering. It will render everything, It means it gives us the same environment as we get on the browser. Enzyme also have mount API which serves the same purpose. So it is not a real advantage over Enzyme

3. No need toforceUpdate

If you are using Enzyme with sinon and spying on some arrow function inside the component then you would have to force update the component

it('should fire handleClick when button is clicked', () => {
const wrapper = shallow(<Component {...props} />
const stubbedHandler = sinon.stub(wrapper.instance(),
'handleClick');
this.setProps({prop1: 'string'}); // OR wrapper.forceUpdate();
chai.assert.isTrue(stubbedEventHandler.calledOnce);
stubbedEventHandler.restore()
}

With React testing library with don’t have to do all. You just have to deal with DOM

4. Avoiding Implementation details

React-testing-library encourages you to avoid implementation detail on your component rather focus on making your tests give you the confidence for which they are intended. This makes your test much more maintainable in the long run. For example, Enzyme lets you update state and props of the component which is actually not the way the user is going to use your application

5. Enforce to write better test cases

React-testing-library encourages us to write better components, follow Accessibility and semantic HTML. It offers very few ways to select a dom element by test-id, placeholder, aria which it is very less likely to get change while you refactor your code.

It gives you much confidence then CSS and id based selectors.

So when I was writing my test cases I realized my elements are not easily accessible so I went back to HTML changed it so it make it accessible. It is like a feedback mechanism about your component.

Code Example

it('Planet Info open and close ', () => {
const props = {
searchPlanet: jest.fn(),
history: {
push: jest.fn()
},
searchInfo: {
success: true,
results: [{ name: 'name1', population: 10 }, { name: 'name2', population: 10 }, { name: 'name3', population: 100 }]
}
}

const { queryByText, getByText, container } = render(<PlanetSearch.WrappedComponent store={store} {...props} />);
const planetItem = getByText('name1');
fireEvent.click(planetItem);
let planetInfo = getByText('Planet Info');
expect(planetInfo).toBeTruthy();
// Close Planet Info const closeBtn = container.querySelector('button[class="close"]');
fireEvent.click(closeBtn);
planetInfo = queryByText('Planet Info');
expect(planetInfo).toBeNull();
});

In the above example, you can see there is no State or Props used which makes it more robust and behavior-driven. As we know the same test in Enzyme will be done in fewer lines of code but that comes with a price of potential test break while refactoring.

Conclusion

I have used Enzyme for the last couple of years and I think it is still very powerful library to test your application and have great community developers and maintainers.

But in the last couple of month with React-testing-library It made me think more from a user's perspective while writing tests, following best practices (Accessibility, Selectors).

I will continue to explore more about it for my future projects.

If you are also working with React and haven’t tried React-testing-library, It is worth having a look at it.

--

--