Complete Intro to React, v3 (feat. Redux, Router & Flow) Shallow Testing with Enzyme
This course has been updated! We now recommend you take the Complete Intro to React, v8 course.
Transcript from the "Shallow Testing with Enzyme" Lesson
>> Brian Holt: I wanna to show you a problem with what we have right now. So if I come in here to ShowCard.jsx and I change this to be, I don't know, I'll put another thing in here,
>> Brian Holt: Something different. So I have changed ShowCard, and I have not changed search.jsx, right?
[00:00:23] If I run test again, what's gonna happen?
>> Brian Holt: Let's do it, yarn test.
>> Brian Holt: I failed my test. So something going wrong in ShowCard is failing my search component test. Now some people say that's fine. I don't care, I just want something to fail, and that can be your opinion.
[00:00:48] It's wrong, but that can be your opinion. Just kidding, I mean maybe. I think it's wrong, but my problem with this is that if there's nothing wrong with Search I don't want Search to fail. I want ShowCard to fail. I want the test for ShowCard to fail so that I immediately have to go and check out ShowCard.
[00:01:09] So let's bring in a library that's actually going to allow us to do that.
>> Brian Holt: In fact I'm gonna leave this for now an we'll fix it here in just a second. [COUGH] So I'll come back to search.spec.jsx,
>> Brian Holt: And we are going to import a library called enzyme.
[00:01:33] So import, shallow, from enzyme.
>> Brian Holt: And we're gonna modify this a little bit and we're also going to drop renderer.
>> Brian Holt: Cuz enzyme is actually going to use renderer underneath the hood so we don't actually have to import it directly, in fact you can't import it directly. You can't have renderer and enzyme in the same import.
[00:02:06] So what we're gonna do here is we're going to, instead of doing renderer.create, we're gonna do shallow.
>> Brian Holt: And then we can actually just do this directly. So expect component to match snapshot.
>> Brian Holt: So what enzyme is the wrapper on top of React Test Renderer? But it's gonna do certain things for us.
[00:02:34] One of the things that it's going to address the problem that I just showed you. It's actually going to stub out all of the children components, right? So, for example, we have ShowCard, right? It's going to not actually go down and render everything in ShowCard. It's just going to say a show card was rendered here with these props, and then it doesn't actually dive down into that child component.
[00:02:56] So, what's awesome about that is it stops caring what's happening in ShowCard, and it will only fail things in Search when something in Search is actually wrong. This is still not gonna work yet, we have to do one more thing. Save that, go to package.json, and we need to tell, you can put this anywhere, wherever.
[00:03:20] We have to give this a jest top level property,
>> Brian Holt: We have to tell jest how to snapshot enzyme components. So what we're gonna do here is we're gonna say snapshotSerializers,
>> Brian Holt: Which is gonna be an array because you could have multiple kinds of serializers, but we'll just have one.
[00:03:49] It's gonna be jest-serializer-enzyme.
>> Brian Holt: So again, what this is doing, this is telling jest hey, whenever you encounter an enzyme component, this is how you serialize it. It's giving it code to know how to serialize that into a snapshot. Does that make sense?
>> Brian Holt: Okay, cool. So, go back to your search.spec.jsx, and now save it.
>> Brian Holt: And come back and run yarn test again.
>> Brian Holt: And now it's gonna fail again because now it has the enzyme output and not the previous output. But this is what the enzyme output looks like. Notice that it was actually going down like rendering The Game Of Thrones, all of the markup inside of ShowCard.
[00:04:50] Now it just says I'm getting a ShowCard, here's the props passed in. I don't know anything else about it, right?
>> Brian Holt: Does that make sense? So let's go ahead and run yarn test:update, so then we can actually just go in and look at the snapshot, okay? So we updated that, and let's go look at the snap, .snap.
[00:05:15] So again, look in here. Rather than actually outputting the markup for ShowCard, it's just actually giving you a React-looking component.
>> Brian Holt: Make sense?
>> Brian Holt: Pretty cool, I think, right? So now, even though that we're messing around with ShowCard in here, so I can go back and delete this.
[00:05:40] Save it, and try running this again and update, just test.
>> Brian Holt: It'll still passes by the fact that I'm changing things in ShowCard. You have a question?
>> Speaker 2: Yeah, Doug's asking, with the test and test update scripts, does that automatically set the environment in v?
>> Brian Holt: It must be.
>> Brian Holt: I had not thought of that.
>> Brian Holt: Yeah, I wonder if jest, let's actually look. I have no idea. So if you look at my notes, I actually have in there setting the node end. But if we go to spec.jsx,
>> Brian Holt: process.env.NODE_ENV. So let's try running that.
>> Brian Holt: Yeah, check that out, it actually sets the NODE_EMV for you.
[00:06:47] Who knew? I did not know that, today I learned.
>> Brian Holt: That is pure, fortunate happenstance. [LAUGH]
>> Brian Holt: So the way that you would handle that in here,
>> Brian Holt: So you could say node env equals test jest, right? And you can change this to be whatever you want, it's like production for your server or whatever.
>> Brian Holt: This is okay if you're using it just for yourself and you're sure that everyone using it is bash. This is not going to work across shells, right? So there's a tool called crossenv which I don't remember the API for it. It looks like this.
>> Brian Holt: And then you provide it like, I think it looks something like that.
[00:07:40] It's another node package that you would install that will take care of all those various different shells to cover. So if you need to be setting your environment across shells, this is how you do it. Enzymes are super cool too, tool. There's an interesting thread on the GitHub for React that they considered making it the official testing speed of React.
[00:08:04] And they ended up not doing it but they said like internal ad Facebook they actually do use enzyme for all their testing. The only reason they don't make it official is they thought it might stunt like the innovation happening around testing in React, so. Nonetheless pretty much any company that's testing React is probably using enzyme.
>> Brian Holt: Okay, so let's go back and look at spec.jsx here. Enzyme has several layers of rendering. The one that you want to be using as much as possible is shallow. You can see that our test is pretty zippy, right? It's not doing anything particularly crazy cuz it's not actually creating some sort of fake DOM or anything like that.
[00:08:48] It's just rendering up the component and testing against the markup that's being rendered there. If you need to go deeper, there's another one called render, and if you wanna go deeper than that there's one called static. You don't have to bring those in, I'm just showing you that they're available.
[00:09:05] Render is actually going to emulate a DOM. With like JS DOM, right? But if you've ever tested with JS DOM before, it's real slow. It's gonna greatly slow down your tests, right? And a fast test speed is a happy test speed in my opinion. Static is actually going to bring in cheerio, if you're familiar with cheerio.
[00:09:24] It's an awesome library for like doing DOM exploring in any node-like environment, so you can actually fetch a page using Ajax in your server and pull stuff off of it. So if you wanna do web scraping, cheerio is a really great way to do it. So that's what static does is it uses cheerio to explore your React component, and those are also available to you.
>> Brian Holt: But again, both static and render are much slower than shallow. Shallow is pretty fast, so stick to shallow where possible.