The React Shallow Renderer test utility lets us inspect the output of a component one level deep. In this lesson, we will examine the rendered output of props, specifically the className
prop. We will then use the ES2015 String.includes()
method to check that our rendered className includes what we expect.
[00:00] Here we have an app that has a few icon components on the screen. We can see that there's a thumbs-up icon and a trashcan icon. Now we want to write some tests to make sure that these icons are rendering correctly.
[00:13] Here we have a test file where we've imported the React library as well as the React testing library, the Expect assertion library, and the component that we want to test, which is the icon. Let's write a test now. We're going to say that it should render the icon. Now let's set up our shallow renderer.
[00:32] I'll say const renderer = testutils.createrRenderer. Then we'll tell this what to render. We'll say render, and we'll give it the icon component with a name prop. Let's use the Facebook icon. At the end of our test, we're going to assert that the actual value is going to equal the expected value.
[00:57] Our actual value is going to be the renderer. If we get the rendered output of that renderer, we will be getting what was returned from this guy right here. So we're going to get "what is icon name" returned when it's rendered and put it inside of this actual variable.
[01:18] Now let's take a look at what this actual value is going to be. We can see here that the shallow renderer has given us our object representation of our component, so we have this giant object here. But what we're really interested in is this className prop right here.
[01:36] Inside of our root object we have the props object. There's a className which is just a string of classes. Now back in my test file I'm going to remove this log statement. Then, instead of checking the entire object output of my shallow renderer, I'm going to only look at the props and the className prop.
[02:00] Now since we know that the className prop is just a string, we can use the ES2015 string method of includes to check that it includes the className that we're looking for, which is Facebook in this case. The way the includes method works is it will return a Boolean value. If Facebook is found in the className string, it will return true, and, if not, it will return false.
[02:23] So we're going to say that our expected value is going to be true. To review, we created our shallow renderer. We gave it the component we wanted to render. Then we grabbed that rendered output and checked that the className prop included the string that we were looking for. Then we assert that that's the case. That's how we can test className props.
Tests not breaking is a feature, generally. Catching React update issues is definitely a solid use case for a test.
Gotcha, I'm just wondering if there is any real business value here.
This is a great example of shallow rendering but at it's core it seems like it is really testing that this.props.string = string
which isn't hugely valuable on its own.
I'm pretty new to testing in general and I guess I'm just asking in general if it's really worth testing and maintaining a use case like this.
Clinton, I think the key to a useful test is that you are testing something that you want to ensure doesn't break without you knowing about it. In the lesson, we look at testing that a string of classnames contains a specific substring to ensure that our icons will be rendered correctly; this is not this.props.string = string
but rather this.props.string.includes('substring')
. In this situation, the value comes in knowing that our icons are rendering correctly - and we don't have to manually check this in the browser any time we make a change to the Icon component.
There are hundreds of other use cases for this, but the principle is that we...
I've found generic tests like this to be very useful :)
"To me it seems like this would almost never break, unless there was a dramatic update in React OR in your testing library."
This is the beauty of it! The only time this test would break is if we screw up our Icon component where it is no longer rendering the correct Icon types - which is what we want. If the test did break we would want to know about it before our users complain "the icons aren't working anymore". The test provides value because it will let us know immidiately if we have broken our key expected functionality in our component without having to manually check the component output in the browser every time we make a change.
Although the example in this lesson is small and simple, the more tests you have like this, the easier it is to add new features and refactor with confidence, which is the true value of testing.
expect
has a toInclude
method that you could use directly!
Hey Concierge. Using the expect-jsx methods gives you nice JSX syntax error diffs. Not required but I find it much easier to debug :)
Hi, I found this course very useful. One thing I'm wondering, are these real tests that you would write in a production app? To me it seems like this would almost never break, unless there was a dramatic update in React OR in your testing library.
https://github.com/trevordmiller/favorite-quotes/blob/master/src/components/Icon.spec.js