I’ve been writing unit tests for React with Karma + Mocha + Expect for about nine months now. While it’s been working well enough, there have been a few moments when I’ve found myself thinking, there’s got to be a better way.

As my team at Concur transitions from one project to the next, we had the opportunity to try out some new and interesting testing frameworks. There are a lot of options out there, and after experimenting with a few, we landed on Unexpected + Unexpected-React.

The difference hasn’t been night and day, but there have been some pleasant niceties worked into the Unexpected framework that makes our lives a little simpler to work with. And, as I’m sure you know, little differences over time make big gains.

Let’s look at some of the diffs.

Writing Tests

Expect is a popular library, so I’m sure this won’t look too unfamiliar. In any case, here’s a random unit test pulled from our KME test stack. Here I’m also using TestUtilsAdditions, a handy helper library.

... instance = ReactTestUtils.renderIntoDocument( <DisplaySettings userRole=”admin” {…props}/> ); expect(TestUtilsAdditions.find(instance, ‘#listing-is-visible’)[0].checked).toBe(false, ‘listing visible failed’);

Expect uses methods off the expect function to evaluate whether or not a test passes or fails. Unexpected is a little different, replacing the method with an argument string. It’s kind of strange, but not difficult to work with. Here’s a basic test written with Unexpected.

const expect = Unexpected.clone().use(UnexpectedReact); ... renderer.render(<ListingDetails listing={null}/>);

return expect(renderer, ‘to have rendered’, <p>no data yet</p>+ );

Above we’re testing using shallow rendering to test this ListingDetails component. There might be a few things here you didn’t expect. First, when using UnexpectedReact we need to return our expect statement.

Next, we have this nice ‘to have rendered’ string that becomes available when you use UnexpectedReact. This leads to my favorite part of the Unexpected paradigm. We can check our text again plain JSX. This becomes a huge time saver in the long run, and also leads to some nice output when our tests fail.

Output

One of the best features of Unexpected is the output. Just take a look: