Check out a free preview of the full Testing React Applications, v2 course:
The "Test a Form Component Solution" Lesson is part of the full, Testing React Applications, v2 course featured in this preview video. Here's what you'd learn in this lesson:

Kent walks through solution to the Test Form Component Exercise for testing for the simple React form login component. Kent takes questions from students.

Get Unlimited Access Now

Transcript from the "Test a Form Component Solution" Lesson

[00:00:00]
>> Kent C. Dodds: Alright, so let's get this underway, so we're writing a test, very basic fundamental test for this login component. It's actually fairly simple, it's not doing any asynchronous stuff. It accepts a single prop and all we need to do is find this input, find this one and fill them out, there are various ways we can go about doing that and then we need to click on there or yeah, submit this form.

[00:00:29] And so let's go ahead and make that happen in our test here. So we're going to import Login from '../login' and we're also gonna be using JSX so import react from react. And then this first step is arranged so I'm gonna create my on submit handler so handle submit, that suggest function.

[00:00:55] And then I'm gonna create my container equals document.createelementdiv. And then I'm going to render, using ReactDom, from react-dom, ReactDom.render, the log-in component with that on submit handler and I'll submit.
>> Kent C. Dodds: There we go, container.
>> Kent C. Dodds: And then we can get a couple of our fields, so there are various ways we can get the fields.

[00:01:32] I'm actually going to get the form field as indicated and this would be container. And then I'll get the fields by their name, so we've got username and password. So username and password = form.elements.
>> Kent C. Dodds: Cool, so that is the arrange step of our test. And then we need to fill out, well, actually sorry, this is still arrange step.

[00:02:05] We need to fill out this form, with some values, so we'll say username.value =, I think I said chucknorris in my solution. Username.password, oops, or sorry, that's password.value = I do not need a password. Because he's Chuck Norris, of course and then that's the arranged step. So, then we can dispatch our submit event, so I'll just copy that, Form.dispatchEvent, then submit Event.

[00:02:43] and because it's not asynchronous, nothing asynchronous is happening, we can actually start making our assertions on this handle submit. So we'll expect handle submit to have been called times one and to have been called with and what should it be called with? Well, our username and our password.

[00:03:10] Actually, we can just keep that there and say, whatever I set the input value to, that's what I want that to be. Cool, so we'll save that, I stopped my test from running, so to start it up again, I'll say npm run test:client. Whoops, I'm in the wrong drape tree, there you go, there you go.

[00:03:33] Npm run test call client and that will start out all the tests that are relevant to the files that I've changed and so I'm just gonna scope it down by hitting the p key, log in, got step 1. Whoops, log in step one dot to do, okay, cool.

[00:03:56] Great, so that is a fundamental no abstraction beyond just regular react API's test. And that's just using regular dom stuff, what questions do you have about this? So here's a question, while you're thinking about what you learned, so are we going to deal with change handlers for the inputs simulating keyboard strokes, etc.?

[00:04:23] Yes, so we won't be doing that for, like we don't have any examples for that, but I can show you how to do that. If you have a dynamic form, you need to show validation as users typing. I can show you how to do that, once we get the abstraction stuff going here in a little bit.

[00:04:43] Yes?
>> off screen male: I saw somebody elementing this in chat, but can you explain why? We have to go through this whole complicated process of creating an event on the window and then having the form dispatch it.
>> Kent C. Dodds: Yeah, so that's actually like the reason that seems complicated is because you're used to something that's simpler and this is actually what those simpler things are doing.

[00:05:10] So a part of the experience of you understanding and having a good grasp of this is understanding what is happening under the hood, so you can use your abstractions more effectively. So, that's why we're gonna switch to an abstraction here in a sec, but yes, thank you.
>> off screen male: Okay, so I was gonna ask a question, because normally I would use refs so that I don't have to do Dom traversal.

[00:05:36]
>> Kent C. Dodds: Okay.
>> off screen male: And is that something that you wanna avoid in a react-testing situation?
>> Kent C. Dodds: Yeah, good question. So, you're saying, in your source code you're gonna be using ref so you don't have to [INAUDIBLE]. So, yeah and whether to do that in the test. So what we're going to, the abstraction we're going to use here in a little bit will actually give us an even better way of selecting the different notes that we're looking for.

[00:06:05] If you wanted to use refs what you would have to do is you would have to expose a prop like UsernameRef=[] and so on and so forth and then those would have to be forwarded on, it could get to be a real pain really fast. Cuz okay, now I'm gonna move this to a separate component now I've got to, you're propt are only refs which would not be fun.

[00:06:27] So yeah we do have a better way to select these components and we'll do that next. That's a good question to lead us in.
>> Kent C. Dodds: Yes?
>> off screen male: I mean, I think just one observation from me. I started unit testing last week for the first time and we were using enzyme, so it was interesting to see actually using React DOM to render.

[00:06:52] You know the components in the actual test
>> Kent C. Dodds: Yeah, yup, so this is, enzyme does a lot of stuff but this is kind of similar. This is like a light weight version of what the mount function does. It does create a domino and it does mount it or it does render it with React Dom, then it adds a whole lot of host of other things that you can do with the wrapper that you get back.

[00:07:21] But, yeah, this is basically what's happening under the hood.