React-Testing-Library (RTL) vs Enzyme
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.
- No need to set up or initialize. With
Enzyme
you need to set up an adaptor to make it working with React 16 but withReact-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.