Reacting, a short guide for react testing

Lucas Bordignon
Zygo Tech
Published in
6 min readJun 16, 2018
It's harder to decide when you have too many options. Thanks max!

React has made web development very easy, accessible and fast these days having a large ecosystem that comes together. However, writing tests for react is not so pretty as developing the frontend of a web app with it.

This article tries to give some hints from a bunch of articles that I have read, trying to find a fast and scalable way to write react tests, with a bit of personal experience and thoughts.

Note: these are my personal ideas, I don't think they're the "ground truth" to this topic. Feel free to give some thoughts and ideas on the comments :)

Testing & Existing Libraries

In Javascript, there are many libraries and frameworks that help us to write clean and fast tests, but, not all of them are designed for the same purpose. Some are just assertion engines, others do mocks, stubs and mocks, and so one.

Some of the common ones that I have seen are the following:

Jasmine

Comes with an assertion engine, mocks functionalities and so one. It served as the influence to Jest. It's a little older, which means it has a large community around it, as Mocha does, and integrates with multiple other libraries and languages(the GitHub repo cites integrations with Python and Ruby).

One of the things that makes Jasmine a little odd to me is that it "pollutes" the global space with multiple constants and imports, which, to me, can drive to write something without knowing whether that thing is defined. As says Python's zen:

"Explicit is better than implicit"

Mocha

Framework with support from large companies, as Yahoo and GitHub, it's very popular in the community. It's very stable and mature, based on its time in the community.

It doesn't come with an assertion or mocking library, but is very flexible and allows the user to integrate with a lot of options (chai and sinon are some examples, respectively).

Jest

Currently, the most popular testing framework(based on GitHub stars), it's written and maintained by the Facebook, which already maintains React. It is an assertion engine, using words like describe and it to write your tests(similar to RSpec's API if you're used to rails testing).

Has an awesome snapshot feature, which we will talk about soon, and is blazingly fast, running your tests in parallel (which brings a few pros and cons). Is the chosen one, for me.

AVA

It's a very new library (at the moment of this writing, it's 1.0 version is in beta), but with a good approach. Very minimalist, without implicit globals and has TypeScript support.

There's not much of what I can write, as haven't worked with it and it is still in beta, but would like to mention it.

Enzyme

A testing utility written by Airbnb, is an excellent tool used to simulate and renders out react components. It's not an assertion library, so we don't need it if we are not working with react.

It has three rendering types, which render only the current component, without its children (shallow), full component rendering (mount) and static rendering (render).

Testing React Components

What should we test? This is one of the hardest questions to make when we're starting to write unit tests for a component. There are some questions that we can make to define the Component's Contract, which is, basically the rules and expected behaviour that your component must have.

This contract helps us the find rules and define what should and shouldn't test. I've found some of them on the community and have tweaked a little to fit my reality.

What we should test

What does the component renders? Maybe it renders nothing or renders an external container with (or without) nested components inside of it. It's important to test the basic structure of the component to ensure that all the expected nested components(if some) are rendered, on their correct order.

Which props the component receives? Most of the changes made on a component are done through props . We must ensure that the right props are being set for all the components inside the external wrapper and, when they change, they are changed on their children if they should.

When passing a function as props, is it called right? The function is called on the right conditions(click, slide, etc.)? It changes what the component renders? Are these changes really happening?

When passing a specific prop, it should change the component? If a given prop is given to it, it must show some different inner component? And it is really rendering it?

Which states the component has? Initial state is right? When an action is taken over the component, are some of the scenarios that we can check for the component's state.

What we should not test

As there are things that are interesting to be tested, some of them may not make much sense or are simply not worthy to do so. Many of this questions are based on this awesome article, by Stephen Scott, which I highly recommend.

Will our test duplicate the component code? If our test will add a line that was written exactly on the same way as it is on the component, won't worth to test.

Each change on the component will imply on the same line on the test file, which is redundant. One example is the css testing, is much better and faster to be done through snapshots.

Are we testing things that have already been tested? If you write tests for components that have their own unit test or are tested through another library (PropTypes, for example), don't test it.

Is this detail an internal or external behaviour? If the tested behaviour is simply an internal behaviour to make the same thing, doesn't make much sense to test it.

Changes on the component's public API (for example, changing props names) are much more important to be tested. "How it will be done" is not so important.

In summary, testing the result of an action or function called is more important than testing its internal code.

Testing Redux

I've seen many articles that write about how to test your components, but most of them don't talk about redux testing. Maybe that's because testing redux is easier(in thesis) and closer to raw javascript testing, but I think it worth to talk about.

Redux can work with three(or four) main components. Reducers, actions, and filters (and constants, in some apps).

Reducers

We can test that a given reducer has an initial state as expected, to ensure that the components depending on that data will start on the correct state.

When actions are dispatched with the given types that the reducer responds to, it changes or ignores the data on the right way.

Actions

Here it comes the complex part on redux testing.

When we are testing synchronous actions, we can simply check that the internal actions are called and it returns the expected result.

When we talk about async actions, doing requests, fetching data, etc. we must take a look on the actions dispatched inside the one we are calling and we must confirm that the right result is saved on our redux store, based on the action’s logic.

It depends on how one writes these actions(with redux-saga, redux-thunk or any other library), but I highly recommend the usage of redux-mock-store, that helps us to check the internal actions dispatched and, as the reducers are tested too, we ensure that the redux store will be with the right data.

Selectors

As imagined, selectors are just filters for our store, very close to what we have on a model(using the MVC framework for any app).

What one can do is populate the store with the data we want to test and write tests to check whether the filters are working on the right way(similar to scope testing, on rails models).

Constants

Not all of the apps have a constants file or something like that, but for those that have, I personally don't see much need to test it.

Most of your constants will be used on reducers and/or actions, so you will already be testing them when writing reducers/actions tests.

Note: think worth mention, redux docs have an awesome section for testing, one should give it a try.

I expect that this article helps to clarify some doubts and questions on React & Redux testing. Would really like to see yours and share with the community about this topic, as is not so easy to find a consensus on this topic!

Thank you for your time! For a further reading, I highly recommend this, this, this and this articles!

--

--