
Testing React Applications, v2 Integration Tests Exercise
This course is no longer being maintained. We recommend the testing section of the Intermediate React course instead. We now recommend you take the Intermediate React, v5 course.
Transcript from the "Integration Tests Exercise" Lesson
[00:00:00]
>> Kent C. Dodds: So this is where this lives. And I actually really strongly recommend that you have a file like this. Utilities that are specific to testing this application. In here, I have a couple of utilities that I employ from React testing library and I use those. And then I just expose it a couple of useful things that we might use through the application.
[00:00:24] So it's almost like your own little node module, like your utility known module that you can pretend that it's published on npm, but it doesn't really have to be. Okay, so this renderWithRouter, it take some UI, so React create element some jsx. It also takes some options. And here we have route is one of those options.
[00:00:47] Because we're mounting the entire application with the router, we can initialize the router to the specific route. That'll default to the home, but you can actually initialize it to be on the registration or on the editor, or wherever you want the app to be at that time. What's cool about rendering with the whole router like this is that you can verify that your route configuration is set up properly.
[00:01:12] So your route exact path equals slash and if you test it like this, then you know that those paths actually work. And it's pretty easy to set up. Because we're not actually in the browser, we're going to create memory history. And that'll simulate the history API, well, actually, it's coming from history.
[00:01:32] So this is how the react router docs work. They're using the memory history. So it keeps track of the back and forward and all of the stack of history in memory. And so we initialize it with the route, so that that's where it is right now. And then we provide that history to our router and then render the UI within the router.
[00:01:58] So all the links and everything will be referencing this instance of the router, whatever it sticks in the context. And then we render that with react-testing-library, we get back our utils. And then we return the utils. And then also, this is one of the reasons why I suggest having utility functions like this, because there are some things that you're going to want to do in several of your tests.
[00:02:26] For example, when we open up this in the first place, if we go to the deployed version, you're gonna see that loading happening right there. What's happening is, actually, it's starting up the server cuz it was asleep. So it'll take a second. When we refresh it, it'll happen really quick.
[00:02:39] But anyway, we start out with the loading. And when I boot up the application, when I render it in the first place, it's gonna try to make a request to say, is this users logged in and let me get all the users and all the posts and everything.
[00:02:52] And so we're going to wait for that loading to go away, just like your user would. A users know that the app is loaded when the loading goes away. And so that because it's a really common thing, we're exposing a finishLoading function that people can call. And so that you don't have to have basically this code.
[00:03:11] It's just a little abstruction that you make yourself and you can use. And that's one of the reasons why I say every project should have a test-utils file for little stuff like this that's kinda specific to that project. But other than that, this operates just like the render method from react-testing-libraries.
[00:03:31] So you'll have your getByText, your getBy so on and so forth, so there's that. And so we render with the router, we render a full app and we get our container and all those things. Got finish by loading. That's the first thing we're gonna do is like, just wait for that loading thing to go away.
[00:03:54] And thhen we'll go ahead and click on the register link. So we're gonna find that, here let's see what we got. Let's log out. So we'll click on the register link. That'll pop up, open this form, and we'll verify that the window location href is registered. So that kind of is confirming, yes, that when I click on that register link, it's taking me to the right page.
[00:04:21] And then we fill out the form, so I'm just gonna generate a login form. I don't care what they are. Get the username and passwords. So this actually is very similar to the test that you just wrote for the login. And that brings up a question that you can ask later.
[00:04:35] Please do ask it later about, okay, so now we're covering the same thing twice, we're testing the same thing twice. Where does it make the most sense? Ask me about that later. So we're gonna get those, all the things that we need. And then before we submit the form, we're going to go ahead and mock out the implementation of post.
[00:04:57] And I'm sorry I couldn't make this any simpler. But you'll probably just wanna look at this and copy and paste how this is working. And then you can talk to me after or something. Ping me on Twitter or something to figure out what's going on or you can just look into the [INAUDIBLE] yourself and figure out what it's doing.
[00:05:16] But anyway, you wanna get the post, you wanna mock its implementation, so that you can return a token. In your case, you'll be logging in with an existing user, so you'll use that user's token, or you'll just return. You can generate a token as well. Just return that token when you're making a post request.
[00:05:41] So that's what's happening here, and then we submit. And then we wait for the loading to go away, so once you log in, it takes to the loading screen. We wait for that to go away. And then we can make some assertions. We assert that the post was indeed called.
[00:05:56] And then it was called with the right arguments. So that fake login form, that fake user, and we call the auth/register endpoint. And then ensure that, after that happen, we set the token so now the user can be logged in. And they refresh the pages, they're still logged in.
[00:06:15] We're no longer on the registration page. We could add an assertion that it only is slash, I suppose. And then we have a getbytestID because this is a username display. There's not really like any aria attributes or anything relevent that we could select. So we're doing a test ID to get the text content.
[00:06:37] And then make sure that the logout appears so actually we can log in with TIL, TIL. And then actually, no, here, we'll register. We're doing registration anyway, TIL, TIL. And loading will go away, and then that's the user display and that's the logout button, okay? And that's pretty much, as a manual tester, what we just did, that's how I verify that it works.
[00:07:05] Okay, my username is displayed there and the logout button is there. All right, and that's it. So I'm gonna set you free for about a half hour. Maybe not quite that long. Maybe we'll do 20 minutes, and you'll be doing the login. So it's client/src/_tests_app.login.todo.