React at scale: Unit Testing
What is unit testing in React? Why do you need it? When do you need it? With which tool? What to test and what not to. All answered here

An analogy I like a lot is that unit testing is like flossing. It doesn’t really give you instant gratification but in the long run it saves you time, money and helps you avoid a lot of pain.
What is unit testing in React?
Unit testing means to verify if a unit of your code is working as expected. It could be a React component, a function, a method, an interaction or a logical behavior. It works by verifying if your unit of code outputs the expected result given an input.
Unit tests in React are tightly coupled with the React component you wrote the test for. Thus you often see project putting tests and react component in the same folder which is a great structure to better separate your concerns.
Why do you need it?
TL,DR: Having unit test will help you and your team move much quicker in the long run. Here’s why:
First, it allows you to make big changes to the code base in a confident manner. It prevents regression issues which could potentially cost multiple hours of fixing. You don’t normally see these issue in a simple To do app. However when a React app hits a certain scale of constantly reusing and modifying a component and it’s getting harder to keep track of the changes around the code base, that’s when unit testing really shines. Here in the team building www.mazda.com.au with a 200,000+ line React code base, unit testing allows us to move quickly with confidence.
Second, having unit tests forces you to write testable code for your React component and this is very important, I would say even more important than the first reason. It makes you produce React component with less side effect, more predictable state, better separated functionally and better readability. It also gives you better understanding of the code you wrote, you started to write code for the expected results, not just for what it does.
React itself is functional and compositional by nature which means it lay a strong foundation for writing testable code by default. It also provide developer a sufficient set of tools to deal with side effects and internal state. Yet many people abuse these tool and make (component lifecycle methods and setState for example) their app less predictable which in turn make it fragile and error-prone. Having a mindset of constantly asking “How should I test this?” is crucial in writing a new React component if you want it to be maintainable.
A popular example is people often want to do a lot of things like data fetching, mutation, logic statements in a single giant method, whether it be in the constructor, a lifecycle method or the render method. This makes the component extremely hard to write unit test for. Having the mindset of writing unit test, you can break them down into multiple functions and methods, each of them have a their own scope and responsibility, this makes writing test a walk in the park as well as contributes to a much more enjoyable development experience. This also allows every member of a big front end team to grab what’s going on much quicker when they look at components that were written by others.
When do you need it?
Every serious React app that involves a team and a client needs unit test.
If you are writing a simple personal project or just putting together components for educational purpose and couldn’t justify spending time writing unit test, it’s fine not to write test. Even in those situation, I would encourage you to write test just for learning purpose.
Which tool should you use
Jest and Enzyme is rapidly becoming the defacto testing combo for React app. Jest is a JavaScript testing framework from Facebook, the creator of React themselves. Enzyme is an assertion library from AirBnB, one of the biggest adopter of React.
You can organise the test to be the same folder as your component and have Jest to run through all of them in watch mode. That way you can keep track of which test is failing when you make changes throughout the code base.
What to test
You don’t use Jest or any JavaScript unit testing framework to test complex UI interaction with sequence of actions, that’s the job of integration testing and usually performed by automated cross browser test runner like Selenium. What you should focus on writing test for is environment agnostic behaviour, here are some of the most common ones:
- Snapshot testing with Jest
- Function(ality) within a component
- Utility methods/functions that are commonly used (e.g. higher-order components)
- Things related to state (e.g. Results of state change, Redux reducers, actions)
- API — test whether you get the expected data
Thanks for reading. Hope you have fun writing tests and feel good looking at the green test passed (who said test doesn’t instantly gratify you again?).
