When writing React component tests, it can be hard to decipher the error diffs of broken tests, since they are just the final objects that React uses under the hood. There are some nice libraries that let you extend your assertion library to show JSX diffs; in this lesson we will wire up one of these libraries to show how to debug JSX error diffs from your React tests. We will also show how narrowing down what you are testing helps to make the test error diffs easier to deal with.
NOTE: This lesson uses the
expect-jsx package, but there are other options available for both expect and other assertion libraries.
Here, we've imported React and the React TestUtils libraries. We've also imported the Expect assertion library. We've created a simple component that we'd like to write a test for. Let's create a describe block for our coolComponent.
We want to test that it should render the greeting, so we'll add our boilerplate shallow-renderer setup, and I want to assert that my actual value is going to equal my expected value, and my actual value is going to be the renderer.getRenderOutput, and my expected value is going to be what we expect our component output to look like. To review, if we call the coolComponent with a greeting of "Hello, World" and it goes through this component, we expect it to come out like this.
Now, let's say we want to change our component, so if we go up here and we want to add an exclamation point at the end of our greeting, now we expect our test to fail. If we run our test, we can see that it is failing, but the diff, or the error isn't very helpful. This is what React looks like under the hood by default, because it's all just objects. To make your test error diffs more helpful, there's some libraries that can extend your assertion library to provide support for JSX.
Since we're using Expect in this lesson, I'm going to install the library called Expect JSX for this functionality. I will run NPM install expect-jsx in my command line, and now that that's done, we'll be able to use it.
Going back to my component file, I'm going to import Expect-JSX, and then I'm going to extend my Expect package with Expect JSX. If we look at the documentation for Expect JSX, we can see that the API consists of three methods.
There's the toEqualJSX, toNotEqualJSX, and then toIncludeJSX. Now, if we take a look at the example, we can see that the toEqualJSX method compares the output of JSX, the toNotEqual method compares that output is different, and then finally the toIncludeJSX method compares that the children or that some piece of the children is included.
I found this last method to be very helpful because it lets you test specific pieces of your rendered output without having brittle ties to your entire HTML structure of your component.
Let's give it a try. Back inside of my component, I'm going to go to my toEqual method and I'm going to change toEqual to be toIncludeJSX. Now, we could run our test like this, but to make it less brittle let's pull out the pieces that are specific to what we're trying to test.
I'm going to remove this div and the greeting title, as well as the bottom div. Now, we can just test this specific greeting piece. Since it's just one element now, we can actually get rid of this wrapping trends.
Now, our test is much simpler and focused on exactly what we're testing. Now, if we run our test again, it's now much easier to see why our test isn't passing. We can see the JSX output, we can see that "Hello, World!" is not the same as "Hello, World" without an exclamation point.
You can see using a JSX diff, it's a lot easier to use and it also helps to narrow down your expected output to exactly what you're testing.