Thursday, December 10, 2015

Warning: Testing React Stateless Components

TL;DR;
Doesn't work right now(React 0.14)

After a long(long long long) time of trying to set up a test environment for my project that was built with stateless components, I had to give up that thought and accept defeat. Because it seems that it is not possible with the current version of React Test Utils.

What is a stateless component

(aka Stateless Functional Components) They are just what it sounds like, it a component that does not use the state at all. It comes with some nice syntax that allows one to write less code because they consist of only one function, the render function. Therefore also doesn't have to extend from "React.Component" or be created with "React.createComponent"-function.

Here's a small example:
var Hello = (props) => {
    return <h1>Hello {props.name}</h1>;
};
<hello name="Anakin"/>

Kinda sweet huh? 

Why would one want to test something so small and simple that only renders some DOM?

It might seem unnecessary to test something like this, but even in the small example above things can go wrong. What happens if we do not supply a name attribute to the Hello-"component"? Well it will render a h1-tag with no name, that seems like something we would want to test, and maybe refactor in the future. An empty h1 is kind of useless and maybe should not be rendered at all? Maybe a default text should be used if the title is empty or not supplied thought the title-attribute.

Here's the keyword "functional". The components are stateless functional components, they can and most likely will have logic in them. A stateless component with no functionality is essentially just a tag and maybe that should not even be a component at all.

Why is this a problem when testing? 

React has a suite of test tools called "React Test Utils", these have tons of uses, one of them is to "fake render" a component so we can inspect it and make sure it behaves as we expect it to. The test util for this is called "renderer" which renders the component in "shadow-DOM" that allows us to inspect it. When trying to use the renderer with a stateless component it will throw an error saying that the argument(the stateless component) is of the wrong type.

There are some issues on github ragarding this. Some people claim they have found work-arounds most of them seems to be about making a wrapper class for stateless components. Personally this feels like the wrong approach and I will take a step back to revert my stateless components to regular ones extending React.Component and await v0.15 where this hopefully is fixed.

1 comment: