1 00:00:01,492 --> 00:00:02,508 Instructor: In the last section, 2 00:00:02,508 --> 00:00:04,050 we made use of this new initialState prop 3 00:00:04,050 --> 00:00:05,490 that we added to our root component 4 00:00:05,490 --> 00:00:08,070 to get some data into our comment list. 5 00:00:08,070 --> 00:00:09,932 So now the last thing we have to do 6 00:00:09,932 --> 00:00:12,450 is write out an actual expectation inside this test. 7 00:00:12,450 --> 00:00:14,220 So I'm gonna delete the console log 8 00:00:14,220 --> 00:00:16,860 and I'll replace it with an expectation. 9 00:00:16,860 --> 00:00:19,440 So we'll look at the wrapped variable right here. 10 00:00:19,440 --> 00:00:22,020 So on wrapped, we're gonna try to find 11 00:00:22,020 --> 00:00:24,300 every ally in this thing, and they'll look 12 00:00:24,300 --> 00:00:27,450 at the length or the number of allies that were found. 13 00:00:27,450 --> 00:00:28,830 So there should be two allies, 14 00:00:28,830 --> 00:00:30,840 since we have two comments right here. 15 00:00:30,840 --> 00:00:34,713 And so I will do a toEqual 2, like so. 16 00:00:37,413 --> 00:00:38,880 All right, so I'll save this file. 17 00:00:38,880 --> 00:00:41,430 I'll trust that this test is gonna run just fine. 18 00:00:41,430 --> 00:00:43,260 For right now, I don't wanna have to flip over 19 00:00:43,260 --> 00:00:45,157 and wait for it to run. 20 00:00:45,157 --> 00:00:46,296 So for right now, 21 00:00:46,296 --> 00:00:48,900 we'll just immediately get started on our next test. 22 00:00:48,900 --> 00:00:51,360 So the next test that we want to work on is to make sure 23 00:00:51,360 --> 00:00:52,920 that the text from each comment 24 00:00:52,920 --> 00:00:54,840 is actually visible on the screen. 25 00:00:54,840 --> 00:00:56,610 Now, it might look like these two tests 26 00:00:56,610 --> 00:00:58,110 that we're putting together right now 27 00:00:58,110 --> 00:01:00,690 are, like, very similar or even identical, 28 00:01:00,690 --> 00:01:02,190 but I would argue that they both serve 29 00:01:02,190 --> 00:01:04,319 a slightly different purpose. 30 00:01:04,319 --> 00:01:06,030 So the goal to first test is to make sure 31 00:01:06,030 --> 00:01:09,240 that exactly one ally shows up per comment. 32 00:01:09,240 --> 00:01:11,850 This test right here is going to actually help to make sure 33 00:01:11,850 --> 00:01:15,210 that we don't have a bug around our list rendering. 34 00:01:15,210 --> 00:01:18,180 For example, we might accidentally have some big bug 35 00:01:18,180 --> 00:01:20,130 inside of our application where we render out, 36 00:01:20,130 --> 00:01:22,650 like, six allies per comment 37 00:01:22,650 --> 00:01:24,660 that gets added to our Redux store. 38 00:01:24,660 --> 00:01:27,180 So that's the goal of this test right here. 39 00:01:27,180 --> 00:01:29,850 Within this test is to make sure that inside those allies 40 00:01:29,850 --> 00:01:31,800 the correct text is actually showing up. 41 00:01:31,800 --> 00:01:34,920 So I would kind of argue that they compliment each other, 42 00:01:34,920 --> 00:01:36,603 do slightly different things. 43 00:01:37,560 --> 00:01:40,890 Anyways, let's flip back over to our CommentList test, 44 00:01:40,890 --> 00:01:43,040 and we'll start working on the second test. 45 00:01:44,460 --> 00:01:47,580 So back over here, I'll add on a new it statement. 46 00:01:47,580 --> 00:01:52,580 We'll say this, it shows the text for each comment. 47 00:01:53,160 --> 00:01:54,460 I think that's reasonable. 48 00:01:57,630 --> 00:01:59,550 So then inside of here, all we have to do 49 00:01:59,550 --> 00:02:03,450 is looked at this old wrapped element right here, 50 00:02:03,450 --> 00:02:06,630 inspect the HTML or the text that it produces 51 00:02:06,630 --> 00:02:08,550 and verify that it contains the text, 52 00:02:08,550 --> 00:02:10,650 Comment 1 and Comment 2. 53 00:02:10,650 --> 00:02:12,360 That's pretty much it. 54 00:02:12,360 --> 00:02:14,700 Now, way back at the start of this application, 55 00:02:14,700 --> 00:02:17,850 we wrote a single test where we looked at the value 56 00:02:17,850 --> 00:02:19,320 of some component or the text 57 00:02:19,320 --> 00:02:22,350 or the HTML produced by a component, 58 00:02:22,350 --> 00:02:24,720 and verified that in fact, yes, 59 00:02:24,720 --> 00:02:26,850 some given text exists inside there. 60 00:02:26,850 --> 00:02:29,460 But that was back before we were using enzyme. 61 00:02:29,460 --> 00:02:32,880 You'll recall we were looking at a particular div 62 00:02:32,880 --> 00:02:36,120 and getting all the HTML that was contained inside that div. 63 00:02:36,120 --> 00:02:38,040 So now that we're using enzyme, we need to come up 64 00:02:38,040 --> 00:02:40,950 with a slightly different way of handling this. 65 00:02:40,950 --> 00:02:43,590 So let's go take a look at the enzyme documentation again, 66 00:02:43,590 --> 00:02:44,730 and we'll get a better sense 67 00:02:44,730 --> 00:02:47,850 of how we can kind of inspect this wrapped element 68 00:02:47,850 --> 00:02:50,163 and find all the text that's in there. 69 00:02:51,330 --> 00:02:54,543 All right, so I'll go back to my enzyme documentation. 70 00:02:55,740 --> 00:02:58,470 Now, I'm gonna show you two different ways of doing this. 71 00:02:58,470 --> 00:02:59,580 I'm gonna show two different ways 72 00:02:59,580 --> 00:03:02,160 'cause there's definitely a very easy way to do it 73 00:03:02,160 --> 00:03:04,260 that will work right away, 74 00:03:04,260 --> 00:03:06,750 but enzyme kind of doesn't really recommend 75 00:03:06,750 --> 00:03:08,670 you do it this way. 76 00:03:08,670 --> 00:03:12,180 So underneath the section for Full DOM Rendering, 77 00:03:12,180 --> 00:03:15,330 I will find the text method, which I have right here. 78 00:03:15,330 --> 00:03:18,030 So we can call the text method on a wrapped element, 79 00:03:18,030 --> 00:03:20,160 and it will return all the text 80 00:03:20,160 --> 00:03:22,950 that is inside of that element. 81 00:03:22,950 --> 00:03:23,820 Now, the reason I say 82 00:03:23,820 --> 00:03:27,270 that enzyme doesn't really recommend this 83 00:03:27,270 --> 00:03:28,710 is that if you look at the documentation 84 00:03:28,710 --> 00:03:31,830 that says this function should be looked at with skepticism 85 00:03:31,830 --> 00:03:34,740 if being used to test what the actual HTML output 86 00:03:34,740 --> 00:03:36,240 of the component will be. 87 00:03:36,240 --> 00:03:38,010 And they don't really say why. 88 00:03:38,010 --> 00:03:39,000 I do not know why. 89 00:03:39,000 --> 00:03:40,623 I'll be honest with you. 90 00:03:40,623 --> 00:03:41,970 I don't know why they say look at this with skepticism. 91 00:03:41,970 --> 00:03:43,260 So they say, if you're trying 92 00:03:43,260 --> 00:03:45,090 to test the actual HTML output, 93 00:03:45,090 --> 00:03:47,010 which is what you and I are trying to do, 94 00:03:47,010 --> 00:03:49,920 then use the render function instead. 95 00:03:49,920 --> 00:03:52,920 So if you want to, you can leave things easy breezy, 96 00:03:52,920 --> 00:03:54,427 call the text method and say, 97 00:03:54,427 --> 00:03:56,910 "Hey, within the text that comes out of this component, 98 00:03:56,910 --> 00:04:00,810 we should find the strings Comment 1 and Comment 2." 99 00:04:00,810 --> 00:04:03,180 But I'll show you the way that enzyme recommends you do it, 100 00:04:03,180 --> 00:04:05,970 which is just a little bit more complicated. 101 00:04:05,970 --> 00:04:08,280 So they say, use the render method instead. 102 00:04:08,280 --> 00:04:10,713 So we will look at the render method. 103 00:04:12,060 --> 00:04:13,950 So here's render right here. 104 00:04:13,950 --> 00:04:15,840 So when you and I call render, 105 00:04:15,840 --> 00:04:18,692 it returns something called a CheerioWrapper. 106 00:04:19,680 --> 00:04:20,850 Well, that kind of begs the question, 107 00:04:20,850 --> 00:04:22,560 what is a CheerioWrapper? 108 00:04:22,560 --> 00:04:26,160 So Cheerio is a library very similar to jQuery. 109 00:04:26,160 --> 00:04:29,430 It allows us to kind of crawl or run queries 110 00:04:29,430 --> 00:04:33,060 or essentially selectors over snippets of HTML. 111 00:04:33,060 --> 00:04:34,667 So if you want to, 112 00:04:34,667 --> 00:04:36,750 you can very quickly pull up the documentation for Cheerio 113 00:04:36,750 --> 00:04:41,010 by doing a Google search for cheerio js. 114 00:04:41,010 --> 00:04:42,750 And I recommend adding the js on there 115 00:04:42,750 --> 00:04:45,200 'cause otherwise, you'll find a breakfast cereal. 116 00:04:46,500 --> 00:04:49,350 All right, so then we'll find the GitHub page right here. 117 00:04:52,890 --> 00:04:54,780 And you'll see a couple of quick examples 118 00:04:54,780 --> 00:04:58,233 on how to use this thing right on their GitHub page. 119 00:04:59,730 --> 00:05:02,400 So on here, essentially, yep, it looks very similar 120 00:05:02,400 --> 00:05:04,830 to how jQuery works, complete with the dollar sign. 121 00:05:04,830 --> 00:05:06,180 Now you don't have to use the dollar sign. 122 00:05:06,180 --> 00:05:07,890 It doesn't have any special meaning. 123 00:05:07,890 --> 00:05:09,720 They just say like, "Hey, if you want to, 124 00:05:09,720 --> 00:05:11,910 you can assign this thing to the dollar sign." 125 00:05:11,910 --> 00:05:13,560 And then you can run selectors on it 126 00:05:13,560 --> 00:05:17,430 and try to pull off different properties off that HTML. 127 00:05:17,430 --> 00:05:19,500 So a really easy way of handling this, 128 00:05:19,500 --> 00:05:22,200 is to take that CheerioWrapper 129 00:05:22,200 --> 00:05:24,060 that gets returned from the render method 130 00:05:24,060 --> 00:05:26,520 and calling exactly what you see on it right here, 131 00:05:26,520 --> 00:05:28,530 the text method. 132 00:05:28,530 --> 00:05:31,410 text, if you do not pass in any argument to it, 133 00:05:31,410 --> 00:05:34,140 will return all the text that's contained 134 00:05:34,140 --> 00:05:36,750 inside of the element that got selected. 135 00:05:36,750 --> 00:05:38,970 So that's what we're going to do. 136 00:05:38,970 --> 00:05:41,850 So I'm gonna flip back over to my code editor, 137 00:05:41,850 --> 00:05:44,280 now that we've seen the long way of doing everything. 138 00:05:44,280 --> 00:05:47,370 Let's again first get started with a simple console log. 139 00:05:47,370 --> 00:05:50,550 So I'll do wrapped.render, 140 00:05:50,550 --> 00:05:52,920 so that's gonna return my Cheerio element, 141 00:05:52,920 --> 00:05:54,990 and then I'll call text on it. 142 00:05:54,990 --> 00:05:57,090 And that should print out all the text 143 00:05:57,090 --> 00:05:58,740 that is rendered by my component. 144 00:06:01,260 --> 00:06:03,660 So after we get this printed out, we should be able 145 00:06:03,660 --> 00:06:06,120 to do a very similar expect, blah, blah, blah 146 00:06:06,120 --> 00:06:10,230 to contain Comment 1 and Comment 2. 147 00:06:10,230 --> 00:06:12,750 So let's save this file, flip back over the terminal, 148 00:06:12,750 --> 00:06:14,850 and see what actually gets console logged. 149 00:06:15,870 --> 00:06:17,120 Right, so back over here. 150 00:06:18,180 --> 00:06:20,220 Again, kinda longer on my test suite. 151 00:06:20,220 --> 00:06:21,603 I apologize for that. 152 00:06:23,160 --> 00:06:24,684 There we go. 153 00:06:24,684 --> 00:06:25,770 So right here, you'll see our console log, 154 00:06:25,770 --> 00:06:27,840 and we get back the very plain text 155 00:06:27,840 --> 00:06:29,550 of Comment 1 and Comment 2. 156 00:06:29,550 --> 00:06:30,720 So it's something to be aware of here 157 00:06:30,720 --> 00:06:32,910 is that when we use that text method, 158 00:06:32,910 --> 00:06:35,490 it returns the actual text that is contained 159 00:06:35,490 --> 00:06:37,440 inside of that entire component, 160 00:06:37,440 --> 00:06:40,920 and it does not return any of the actual HTML. 161 00:06:40,920 --> 00:06:43,140 So when we use text, it's specifically to look 162 00:06:43,140 --> 00:06:46,383 at the visible text that is returned by the component. 163 00:06:47,340 --> 00:06:50,100 Okay, so we clearly get back Comment 1 and Comment 2, 164 00:06:50,100 --> 00:06:51,600 which means back inside of our test, 165 00:06:51,600 --> 00:06:53,130 I will clean up the console log 166 00:06:53,130 --> 00:06:56,130 and we'll replace it with an actual expectation. 167 00:06:56,130 --> 00:07:00,990 So I will say expect wrapped.render .text, 168 00:07:00,990 --> 00:07:03,633 and we'll do the toContain matcher again. 169 00:07:05,190 --> 00:07:09,513 And I will expect that to contain the string of Comment 1. 170 00:07:10,620 --> 00:07:12,153 So Comment 1. 171 00:07:13,350 --> 00:07:16,170 And then I will do the exact same thing a second time, 172 00:07:16,170 --> 00:07:21,170 wrapped.render .text toContain Comment 2. 173 00:07:22,530 --> 00:07:24,150 So I think you have a pretty reasonable idea 174 00:07:24,150 --> 00:07:25,260 of what's going on here. 175 00:07:25,260 --> 00:07:28,170 We cannot test for multiple toContains 176 00:07:28,170 --> 00:07:29,790 inside of a single expectation. 177 00:07:29,790 --> 00:07:31,830 That's why we did two separate toContains 178 00:07:31,830 --> 00:07:33,540 or two separate expectations. 179 00:07:33,540 --> 00:07:35,910 One's gonna specifically look for Comment 1 180 00:07:35,910 --> 00:07:38,910 and the second one is specifically looking for Comment 2. 181 00:07:38,910 --> 00:07:40,860 Now, I guess you could technically do something, 182 00:07:40,860 --> 00:07:42,450 like Comment 2 like that 183 00:07:42,450 --> 00:07:44,220 and combine it all into one expectation. 184 00:07:44,220 --> 00:07:47,760 But yeah, probably not gonna want to do that. 185 00:07:47,760 --> 00:07:49,200 All right, so we'll save this file, 186 00:07:49,200 --> 00:07:51,030 we'll flip back over the terminal, 187 00:07:51,030 --> 00:07:54,150 and it looks like all of our tests are good to go. 188 00:07:54,150 --> 00:07:55,500 Awesome. 189 00:07:55,500 --> 00:08:00,270 So that is the basics of testing with React and Redux, 190 00:08:00,270 --> 00:08:01,200 the very basics. 191 00:08:01,200 --> 00:08:03,750 So we've gone over testing list components, 192 00:08:03,750 --> 00:08:06,420 calling action creators, testing action creators, reducers, 193 00:08:06,420 --> 00:08:08,160 all that kinda good stuff. 194 00:08:08,160 --> 00:08:09,330 But I think you'll agree with me 195 00:08:09,330 --> 00:08:11,070 that while we've kind of, you know, 196 00:08:11,070 --> 00:08:13,110 done a good overview of testing, 197 00:08:13,110 --> 00:08:16,890 we haven't really seen a lot of super practical stuff. 198 00:08:16,890 --> 00:08:20,190 So I want to add in one more function or one more piece 199 00:08:20,190 --> 00:08:23,520 of functionality to my component here, my application. 200 00:08:23,520 --> 00:08:25,080 So let's take a quick pause right here. 201 00:08:25,080 --> 00:08:26,130 We'll come back the next section 202 00:08:26,130 --> 00:08:28,563 and talk about exactly what we're going to add.