Functional styled code

When we say testing we mean that a unit returns the same output for the same input. But how can we be sure that it’s always the same? This is where FP helps us. FP says that every function should be pure, but what does a pure function mean? You can read it at Wikipedia, but this is a brief explanation:

Return the same output for the same input. Returning value cannot depend on any hidden information or on internal state. No side-effects. A side-effect is usually network requests, some mutations or mutable objects. No global variables. A function cannot depend on global variables. Do not overwrite arguments. Arguments are immutable. Easy to test. Don’t need to mock anything or provide. All a function needs are arguments.

The basic example of a pure function would be:

But how does a ‘pure’ react component look like? It’s just a view. A dump component. It only should render props and has no state. This is an explanation of how to split your component as dump and smart.

This component always renders the same html for the same props.

Setup

There are a few tools which can help you to test your code. As a test runner, I use Jest because it works with react out of a box. For testing react components we are going to use Jest snapshot and react-test-renderer. Jest snapshot compares two components’ outputs, one from the previous run(if it was run before) and one from the current run. Jest stores a component’s output to a file when we run a test in a very first time and later on jest compares that ‘snapshot’ with what the component renders now. React-renderer needs for rendering components and get JSON out of it, jest takes the JSON and uses it as a snapshot.

It is easy to set it up, all you need to do is written here(1 command).

Unit testing

In unit testing, everything is a unit. We don’t test any functionality, we don’t test any data, everything that we test is returning value. For a component, it is HTML code, for a function it might be everything: function, an object, boolean, string and etc.

Let’s write a test for our small and pure function:

The sum function always returns 4 if 2 and 2 are passed as arguments. There’s no way to get a different result for the same args.

Let’s now write a unit test for a dump component.

That’s it. A unit test only checks whether a component was rendered correctly. It does not check whether an onClick function was called or not. What does it give us?

Assure us that a component renders the same as it did before. A component is rendered correctly.

Not too bad for 4 lines of code, but can we get more? We can. This is where functional testing helps us.

Functional testing

What if our function has its own state? What if we need to test that an onClick function gets called with something passed as an argument? Let’s say we have a button which shows a number of click on it as a label and whenever we click on it it calls a function passed as a prop with the current amount of clicks?

What we can test here:

A component is rendered correctly. When a component is rendered the counter is equal to 0. When we click on the button it calls the onChange function only ones. When we click on the button it updates it’s own state and call an onClick function with the counter.

We start from the first one:

Pretty simple.

The second one, we need to get access to the component’s state. We can do it using an instance of the renderer.create function.

To test the third one we need to use jest.fn as a mock function and later we need to check whether it was called or not.

The last one but not the least. Here we need to simulate a click on the button, we can do it in two ways: using React-test-utils or using Enzyme. I prefer to use the second one because it’s simpler and more intuitive. With Enzyme you can also set a component’s context, props, finding elements by classnames or tags(like JQuery). You can set it up with only 1 command.

Conclusion

Now we know what’s the difference between unit testing and function in react world. Writing unit tests is faster but it doesn’t give you feeling that your component is working correctly. It just assures you that a component is rendered and it doesn’t look differently from its previous render. If you don’t pass an onClick function at all your component might get broken when a user tries to click on it. Functional testing is hard to write because you need to understand what are you testing but it gives you more. Ideally writing unit and functional tests together will make your application bug-free and your users happy. Any test is good if it presents ;)

P.S. What’s next? Testing simple react components is easy, but what we you have relay, redux, react-intl, material-ui theme and others? We will talk about testing complex react components in the next article. Soon.