1 00:00:06,600 --> 00:00:07,560 - In this section, 2 00:00:07,560 --> 00:00:09,990 we're going to investigate full DOM rendering 3 00:00:09,990 --> 00:00:12,540 in Enzyme using the mount function. 4 00:00:12,540 --> 00:00:16,470 You give it a component and you get back a wrapper. 5 00:00:16,470 --> 00:00:19,710 The mount function renders the entire DOM tree 6 00:00:19,710 --> 00:00:22,650 for the component plus all its descendants, 7 00:00:22,650 --> 00:00:24,480 you get full DOM rendering. 8 00:00:24,480 --> 00:00:26,220 It'll render your component. 9 00:00:26,220 --> 00:00:28,560 And if your component calls other components, 10 00:00:28,560 --> 00:00:30,840 they will also be expanded. 11 00:00:30,840 --> 00:00:33,270 And that's how it's different from the shallow function 12 00:00:33,270 --> 00:00:34,350 which we looked at earlier. 13 00:00:34,350 --> 00:00:36,720 When you call the shallow function from before, 14 00:00:36,720 --> 00:00:39,210 it just renders the top level component. 15 00:00:39,210 --> 00:00:42,420 It has child components, but it doesn't expand them. 16 00:00:42,420 --> 00:00:44,670 But when you call the mount function here, 17 00:00:44,670 --> 00:00:46,710 it does expand all child components. 18 00:00:46,710 --> 00:00:48,450 You get back the whole DOM tree 19 00:00:48,450 --> 00:00:51,660 for everything underneath this component, okay? 20 00:00:51,660 --> 00:00:55,560 So that means you can test how your component 21 00:00:55,560 --> 00:00:57,510 interacts with it's child components. 22 00:00:57,510 --> 00:01:00,720 When you pass parameters into your child components, 23 00:01:00,720 --> 00:01:03,300 do they get rendered properly as well? 24 00:01:03,300 --> 00:01:07,080 The whole DOM structure is expanded. 25 00:01:07,080 --> 00:01:10,020 So to show the tests, go into this folder, 26 00:01:10,020 --> 00:01:12,197 lesson 10, Enzyme_FullDom. 27 00:01:13,140 --> 00:01:14,550 Again, I've got a demo application. 28 00:01:14,550 --> 00:01:16,890 It's the same demo application as before 29 00:01:16,890 --> 00:01:18,420 but the tests are different this time. 30 00:01:18,420 --> 00:01:21,510 A quick reminder what the application looks like. 31 00:01:21,510 --> 00:01:23,490 If you do an NPM install, 32 00:01:23,490 --> 00:01:27,420 and then do an NPM start, I've got a product item class, 33 00:01:27,420 --> 00:01:31,290 I've got app component, a product list component, 34 00:01:31,290 --> 00:01:34,680 a product component that displays each product 35 00:01:34,680 --> 00:01:36,240 and then a total value component 36 00:01:36,240 --> 00:01:38,040 which calculates the total cost. 37 00:01:38,040 --> 00:01:41,100 So the example scenario is familiar. 38 00:01:41,100 --> 00:01:45,630 The tests we're gonna look at now have moved on, okay? 39 00:01:45,630 --> 00:01:47,850 So here's the demo app. 40 00:01:47,850 --> 00:01:50,040 If you look in the source folder, 41 00:01:50,040 --> 00:01:51,270 the product list component 42 00:01:51,270 --> 00:01:53,370 is, again, what we're going to test, 43 00:01:53,370 --> 00:01:56,820 a product list receives an array of products. 44 00:01:56,820 --> 00:01:59,670 It'll either say there are no products in stock 45 00:01:59,670 --> 00:02:02,880 if the array is empty or for each product 46 00:02:02,880 --> 00:02:07,230 it'll generate a product element 47 00:02:07,230 --> 00:02:09,540 to display one of those blue boxes 48 00:02:09,540 --> 00:02:11,670 and a total value component at the end 49 00:02:11,670 --> 00:02:12,780 that adds the values up. 50 00:02:12,780 --> 00:02:15,840 Oh, and also a heading to say there are three products 51 00:02:15,840 --> 00:02:17,070 in stock. 52 00:02:17,070 --> 00:02:21,420 So again, the code we're testing is the same as before, 53 00:02:21,420 --> 00:02:23,850 but the tests themselves are now going to use 54 00:02:23,850 --> 00:02:26,040 the mount function as opposed to using 55 00:02:26,040 --> 00:02:27,870 the shallow function from before. 56 00:02:27,870 --> 00:02:29,340 Okay, so the mount function, 57 00:02:29,340 --> 00:02:32,527 when you call mount, it returns a ReactWrapper. 58 00:02:33,416 --> 00:02:35,880 In the previous section, 59 00:02:35,880 --> 00:02:37,830 when we called the shallow function 60 00:02:37,830 --> 00:02:40,560 it returned an object called ShallowWrapper. 61 00:02:40,560 --> 00:02:42,360 When you call the mount function here, 62 00:02:42,360 --> 00:02:44,010 it returns a ReactWrapper. 63 00:02:44,010 --> 00:02:48,270 Very similar, it functions allows you to end the content 64 00:02:48,270 --> 00:02:50,310 that's been rendered, find, 65 00:02:50,310 --> 00:02:52,470 and then you can give it a CSS selector, 66 00:02:52,470 --> 00:02:56,820 the name of an element or the CSS class 67 00:02:56,820 --> 00:02:58,920 or an ID of an element. 68 00:02:58,920 --> 00:03:01,590 And it gives you back a collection 69 00:03:01,590 --> 00:03:04,440 of everything that matches that selector. 70 00:03:04,440 --> 00:03:07,860 Okay, you can get all children for an element, 71 00:03:07,860 --> 00:03:10,650 you can get back the first child, the last child, 72 00:03:10,650 --> 00:03:12,513 this is similar to ShallowWrapper. 73 00:03:14,040 --> 00:03:16,920 Check the properties that have passed into a component, 74 00:03:16,920 --> 00:03:19,950 get the value of one of the properties with a particular key 75 00:03:19,950 --> 00:03:21,834 and so on and so on and so on. 76 00:03:21,834 --> 00:03:25,140 Okay, to the documentation here, Enzyme JS. 77 00:03:25,140 --> 00:03:28,050 If you go to the mount web page here, 78 00:03:28,050 --> 00:03:30,870 the documentation, let's take a quick look, should we? 79 00:03:30,870 --> 00:03:32,428 Here we are. 80 00:03:32,428 --> 00:03:35,130 This is the mount API documentation. 81 00:03:35,130 --> 00:03:38,460 So again, it's quite straightforward 82 00:03:38,460 --> 00:03:40,800 and very similar to ShallowWrapper. 83 00:03:40,800 --> 00:03:42,063 So a little bit of an explanation here 84 00:03:42,063 --> 00:03:44,730 that gives you the broad idea. 85 00:03:44,730 --> 00:03:48,210 And then a detailed look and all the functions available 86 00:03:48,210 --> 00:03:49,983 in this ReactWrapper object. 87 00:03:50,880 --> 00:03:53,280 Find whether some condition is true, 88 00:03:53,280 --> 00:03:56,280 give me back all elements that match some kind of predicate. 89 00:03:57,150 --> 00:04:00,990 Okay, so very similar to ShallowWrapper. 90 00:04:00,990 --> 00:04:03,900 Remember the difference, when you call mount 91 00:04:03,900 --> 00:04:06,660 it expands all of your child components 92 00:04:06,660 --> 00:04:09,450 so you can drill down into the descendant hierarchy 93 00:04:09,450 --> 00:04:11,010 if you need to. 94 00:04:11,010 --> 00:04:16,010 Okay, so here's the first test in productlist.test.tsx. 95 00:04:17,490 --> 00:04:20,430 So I invoke my product list component. 96 00:04:20,430 --> 00:04:21,540 I mount it. 97 00:04:21,540 --> 00:04:24,870 This will expand all child components as well 98 00:04:24,870 --> 00:04:26,193 but as an empty array. 99 00:04:27,030 --> 00:04:29,730 Quick reminder of what that component should render 100 00:04:29,730 --> 00:04:31,140 in that case. 101 00:04:31,140 --> 00:04:34,410 So back in our code, my product list component, 102 00:04:34,410 --> 00:04:37,800 if the array of products that we pass in, 103 00:04:37,800 --> 00:04:39,510 if it's an empty array, 104 00:04:39,510 --> 00:04:43,350 then what we should get back is something like that. 105 00:04:43,350 --> 00:04:44,700 Right? 106 00:04:44,700 --> 00:04:49,560 And not any products and not any total value, okay? 107 00:04:49,560 --> 00:04:51,900 We just basically, that's all we should get back. 108 00:04:51,900 --> 00:04:53,700 So let's check, right? 109 00:04:53,700 --> 00:04:55,001 So mount, 110 00:04:55,001 --> 00:04:57,570 again, this is not a great name for it. 111 00:04:57,570 --> 00:04:59,340 A better name for this function would've been 112 00:04:59,340 --> 00:05:03,360 render component plus all sub-components please. 113 00:05:03,360 --> 00:05:05,220 But that's mount and see what it does. 114 00:05:05,220 --> 00:05:06,723 Let's check what we get back. 115 00:05:07,950 --> 00:05:12,950 If we find H1 elements that gives you back a collection. 116 00:05:13,170 --> 00:05:16,740 The length of that collection, there should be one, H1. 117 00:05:16,740 --> 00:05:20,850 Let's get the first H1 and let's look at the text inside it. 118 00:05:20,850 --> 00:05:24,510 The text inside it should be, no products in stock, 119 00:05:24,510 --> 00:05:26,190 no products in stock. 120 00:05:26,190 --> 00:05:27,750 Good. 121 00:05:27,750 --> 00:05:31,140 There should not be any product element 122 00:05:31,140 --> 00:05:34,440 and there should not be any total value element, okay? 123 00:05:34,440 --> 00:05:37,020 If I look for products and total values 124 00:05:37,020 --> 00:05:40,200 in my rendered content, they should not be there 125 00:05:40,200 --> 00:05:42,810 because we didn't go into that part 126 00:05:42,810 --> 00:05:46,020 of the component functionality, we just went into here. 127 00:05:46,020 --> 00:05:48,630 So the code we've written so far is pretty much the same 128 00:05:48,630 --> 00:05:50,580 as it would've been for shallow rendering. 129 00:05:50,580 --> 00:05:53,670 It starts to get a bit more interesting when products 130 00:05:53,670 --> 00:05:55,620 and total values are actually rendered, 131 00:05:55,620 --> 00:05:58,440 because then we can see how are they rendered 132 00:05:58,440 --> 00:06:00,900 not just whether they're rendered. 133 00:06:00,900 --> 00:06:03,240 Right, so here is a partial listing 134 00:06:03,240 --> 00:06:06,120 where I've actually passed in real data 135 00:06:06,120 --> 00:06:08,190 into my product list component. 136 00:06:08,190 --> 00:06:09,840 So remember in my test, 137 00:06:09,840 --> 00:06:12,690 products was an array of three products. 138 00:06:12,690 --> 00:06:17,670 So my product list component is receiving three products. 139 00:06:17,670 --> 00:06:19,410 Again, before we look at the test, 140 00:06:19,410 --> 00:06:21,270 let's just remind ourselves what we expect 141 00:06:21,270 --> 00:06:22,710 to get back first. 142 00:06:22,710 --> 00:06:26,370 So here's my product list component again. 143 00:06:26,370 --> 00:06:27,930 With an array of products, 144 00:06:27,930 --> 00:06:32,640 we should get back an H1, three products in stock. 145 00:06:32,640 --> 00:06:36,900 It should then render the product component three times. 146 00:06:36,900 --> 00:06:39,870 What's different now when you call the mount function 147 00:06:39,870 --> 00:06:42,720 is that it will actually expand that product. 148 00:06:42,720 --> 00:06:44,520 It won't just say, oh, there's a product, 149 00:06:44,520 --> 00:06:46,350 it will actually invoke that product component 150 00:06:46,350 --> 00:06:49,620 and include it in my result set. 151 00:06:49,620 --> 00:06:53,460 So I should get back three actual product components 152 00:06:53,460 --> 00:06:55,350 actually rendered, okay? 153 00:06:55,350 --> 00:06:57,030 So I should be getting back, 154 00:06:57,030 --> 00:07:00,870 for each product I should be getting back that in my result. 155 00:07:00,870 --> 00:07:04,050 I should be able to see a div with a product item 156 00:07:04,050 --> 00:07:07,830 and the description like skis and the price and in stock. 157 00:07:07,830 --> 00:07:12,090 That should actually appear in my result set. 158 00:07:12,090 --> 00:07:14,610 Right, let's see what we get back then. 159 00:07:14,610 --> 00:07:18,240 Interestingly, the resultant document structure 160 00:07:18,240 --> 00:07:21,150 contains both the component like product 161 00:07:21,150 --> 00:07:23,205 plus it's rendered content. 162 00:07:23,205 --> 00:07:24,570 So you can actually get both. 163 00:07:24,570 --> 00:07:29,070 You can see there should have been three product components 164 00:07:29,070 --> 00:07:31,110 in my result document, okay? 165 00:07:31,110 --> 00:07:33,830 So the product component is still part 166 00:07:33,830 --> 00:07:35,310 of the document structure. 167 00:07:35,310 --> 00:07:38,320 There should have been three product components rendered 168 00:07:39,450 --> 00:07:43,890 and each product is actually expanded, okay? 169 00:07:43,890 --> 00:07:45,720 So for each product, 170 00:07:45,720 --> 00:07:48,720 it should basically render it like this. 171 00:07:48,720 --> 00:07:50,670 So if I've got three products, 172 00:07:50,670 --> 00:07:53,040 I should have three of these as well. 173 00:07:53,040 --> 00:07:54,630 One for each product. 174 00:07:54,630 --> 00:07:59,550 Each of those divs is basically a different product, okay? 175 00:07:59,550 --> 00:08:01,470 With a certain class. 176 00:08:01,470 --> 00:08:04,530 So I should have got three divs 177 00:08:04,530 --> 00:08:07,140 with a CSS class of product item. 178 00:08:07,140 --> 00:08:10,860 If I search for div with a CSS class product item, 179 00:08:10,860 --> 00:08:13,290 I should have a length of three, okay? 180 00:08:13,290 --> 00:08:16,050 So I basically got three products being rendered. 181 00:08:16,050 --> 00:08:18,960 What I can then do is to say, well, let's look at each one. 182 00:08:18,960 --> 00:08:23,160 This code here checks the content of the first product 183 00:08:23,160 --> 00:08:25,920 and basically verifying for the first product, 184 00:08:25,920 --> 00:08:28,260 did it display the correct content 185 00:08:28,260 --> 00:08:29,943 that I'm expecting in my test? 186 00:08:31,200 --> 00:08:32,498 Right, well, let's see. 187 00:08:32,498 --> 00:08:34,770 Let's have a look at this code, right? 188 00:08:34,770 --> 00:08:37,470 So there were gonna be three divs 189 00:08:37,470 --> 00:08:42,060 for those three blue boxes, give me the first one. 190 00:08:42,060 --> 00:08:43,260 Give me div 0. 191 00:08:43,260 --> 00:08:46,410 That's the first product, I've called it product 0. 192 00:08:46,410 --> 00:08:51,410 Product 0 is basically this, okay? 193 00:08:51,930 --> 00:08:53,280 I'm now looking at that. 194 00:08:53,280 --> 00:08:54,140 That's product 0. 195 00:08:55,228 --> 00:08:59,840 And I can say in that product 0, find an H2 element, 196 00:09:00,810 --> 00:09:03,840 find the first H2 and check the text. 197 00:09:03,840 --> 00:09:05,220 It should be skis. 198 00:09:05,220 --> 00:09:07,440 I know what data I've passed in. 199 00:09:07,440 --> 00:09:09,930 I know that the first product was skis. 200 00:09:09,930 --> 00:09:11,580 There should be an H2 201 00:09:11,580 --> 00:09:15,690 and the text of that H2 should be skis, the description. 202 00:09:15,690 --> 00:09:18,480 So I'm basically checking that this part 203 00:09:18,480 --> 00:09:19,313 was rendered correctly. 204 00:09:19,313 --> 00:09:21,660 So this is what you can do with the mount function. 205 00:09:21,660 --> 00:09:23,610 You can forensically analyze 206 00:09:23,610 --> 00:09:26,970 exactly what's been rendered if you want to. 207 00:09:26,970 --> 00:09:28,473 Okay, let's check that. 208 00:09:29,355 --> 00:09:31,353 There's also a price paragraph. 209 00:09:33,510 --> 00:09:38,021 In my first product, let's find all paragraphs. 210 00:09:38,021 --> 00:09:38,940 There are actually two paragraphs. 211 00:09:38,940 --> 00:09:40,290 Did you notice? 212 00:09:40,290 --> 00:09:41,880 There's a paragraph for the price 213 00:09:41,880 --> 00:09:44,580 and a paragraph for the in stock. 214 00:09:44,580 --> 00:09:46,170 I'm gonna check both of them. 215 00:09:46,170 --> 00:09:51,170 So, first of all, let's check paragraph 0, okay? 216 00:09:51,960 --> 00:09:53,250 So that would be the first paragraph 217 00:09:53,250 --> 00:09:55,200 because obviously it starts to compute at zero. 218 00:09:55,200 --> 00:09:57,690 Let's check that first paragraph. 219 00:09:57,690 --> 00:10:01,803 Is its text a price of a thousand, okay? 220 00:10:04,327 --> 00:10:06,270 I'm basically checking the test text here, 221 00:10:06,270 --> 00:10:07,680 price, a thousand. 222 00:10:07,680 --> 00:10:09,630 That's the first paragraph. 223 00:10:09,630 --> 00:10:11,460 What about paragraph one, okay? 224 00:10:11,460 --> 00:10:13,410 So that would be the next paragraph. 225 00:10:13,410 --> 00:10:15,930 Its text should be in stock five. 226 00:10:15,930 --> 00:10:17,610 Obviously the numbers here are hard coded 227 00:10:17,610 --> 00:10:20,340 but you tend to do that when you write uni tests. 228 00:10:20,340 --> 00:10:22,350 You pass in some data that's known 229 00:10:22,350 --> 00:10:24,270 and then you check actual content. 230 00:10:24,270 --> 00:10:26,310 It should be displaying these actual words 231 00:10:26,310 --> 00:10:28,830 based on my test data that I'm passing in. 232 00:10:28,830 --> 00:10:31,478 In stock should be five, okay? 233 00:10:31,478 --> 00:10:32,340 So I'm checking. 234 00:10:32,340 --> 00:10:35,280 Did it display in stock five correctly? 235 00:10:35,280 --> 00:10:38,790 So I've got similar code for the second product 236 00:10:38,790 --> 00:10:39,810 and the third product. 237 00:10:39,810 --> 00:10:43,920 This ... is actually expanded in my code. 238 00:10:43,920 --> 00:10:46,560 Let me show you in my actual code. 239 00:10:46,560 --> 00:10:48,273 I had so much fun writing this. 240 00:10:49,410 --> 00:10:51,810 We are looking at here now, aren't we? 241 00:10:51,810 --> 00:10:56,670 So I've just shown you in the slide, in the PowerPoint, 242 00:10:56,670 --> 00:10:59,910 I've just basically shown you a check for product 0, 243 00:10:59,910 --> 00:11:01,470 that was the skis. 244 00:11:01,470 --> 00:11:03,420 And then I've got exactly the same test 245 00:11:03,420 --> 00:11:08,130 for the next product, the product number one, 246 00:11:08,130 --> 00:11:10,290 that should have been the ski boots. 247 00:11:10,290 --> 00:11:12,150 And then I've got the same test again 248 00:11:12,150 --> 00:11:13,473 for product number two. 249 00:11:15,660 --> 00:11:17,010 And that should be goggles. 250 00:11:17,010 --> 00:11:22,010 So you can be as detailed as you want to be in your tests. 251 00:11:22,680 --> 00:11:24,273 Okay, what about the last part? 252 00:11:25,261 --> 00:11:27,660 That last part there is checking the total value. 253 00:11:27,660 --> 00:11:32,010 Check first of all that the total value component exists. 254 00:11:32,010 --> 00:11:34,350 It will be rendered with the mount function, 255 00:11:34,350 --> 00:11:37,560 it will render the total value component. 256 00:11:37,560 --> 00:11:40,950 Quick reminder, here's my total value component. 257 00:11:40,950 --> 00:11:44,793 I'm expecting to get back a div with a total value class. 258 00:11:45,660 --> 00:11:46,800 This is actually quite useful 259 00:11:46,800 --> 00:11:48,210 because when I wrote this code originally, 260 00:11:48,210 --> 00:11:50,850 I did actually get my algorithm incorrect 261 00:11:50,850 --> 00:11:53,010 and the test found it for me 262 00:11:53,010 --> 00:11:54,630 which I thought was quite useful. 263 00:11:54,630 --> 00:11:57,090 So I'm basically really checking this algorithm. 264 00:11:57,090 --> 00:12:01,230 Is it actually calculating the total cost properly? 265 00:12:01,230 --> 00:12:03,180 According to my maths, 266 00:12:03,180 --> 00:12:05,280 if you look at the actual test that I passed in, 267 00:12:05,280 --> 00:12:06,870 the data that was passed in, 268 00:12:06,870 --> 00:12:09,450 if you kind of multiply each number, 269 00:12:09,450 --> 00:12:11,370 these two things and add them together, 270 00:12:11,370 --> 00:12:15,178 it comes to 5,000 plus 1,000 plus 1,000. 271 00:12:15,178 --> 00:12:18,060 7,000 should be the total cost, okay? 272 00:12:18,060 --> 00:12:21,123 So I'm expecting that there should be, 273 00:12:22,230 --> 00:12:24,423 I'm expecting there to be a div, 274 00:12:25,350 --> 00:12:27,810 basically total value, 7,000. 275 00:12:27,810 --> 00:12:28,860 So first of all, 276 00:12:28,860 --> 00:12:33,840 establish that the total value component was rendered, okay? 277 00:12:33,840 --> 00:12:38,840 That should then render a div with a total value class 278 00:12:39,030 --> 00:12:44,030 and the text inside it should be total value, 7,000. 279 00:12:44,220 --> 00:12:48,210 That's what we expect to get back from our component. 280 00:12:48,210 --> 00:12:50,880 Total value, 7,000. 281 00:12:50,880 --> 00:12:54,120 Okay, so there's a lot of code you can write here. 282 00:12:54,120 --> 00:12:56,520 Whether you want to check things to that level of detail 283 00:12:56,520 --> 00:12:59,370 is entirely up to you, but you can if you want to. 284 00:12:59,370 --> 00:13:00,960 You just need to run the test now, 285 00:13:00,960 --> 00:13:04,200 and fingers crossed, toes crossed, is it gonna work? 286 00:13:04,200 --> 00:13:05,033 Yes.