1 00:00:06,570 --> 00:00:08,100 - In the previous section 2 00:00:08,100 --> 00:00:11,400 we had a look at the simple application 3 00:00:11,400 --> 00:00:14,250 which contained a header component. 4 00:00:14,250 --> 00:00:17,040 It was an example for HelloWorld. 5 00:00:17,040 --> 00:00:18,903 Let's just take a quick reminder. 6 00:00:19,799 --> 00:00:20,632 Here it is. 7 00:00:20,632 --> 00:00:23,340 In the source folder, underneath app 8 00:00:23,340 --> 00:00:24,870 there was a header component. 9 00:00:24,870 --> 00:00:27,048 It was a very simple example. 10 00:00:27,048 --> 00:00:28,800 And we saw what the test script looked like. 11 00:00:28,800 --> 00:00:31,560 And we discussed the purpose of the 12 00:00:31,560 --> 00:00:32,760 of these various things. 13 00:00:32,760 --> 00:00:36,843 Creating a dummy module that knows about my component, 14 00:00:37,710 --> 00:00:42,120 compiling the HTML into JavaScript for that component, 15 00:00:42,120 --> 00:00:45,630 asking the test bed to create an instance of that component. 16 00:00:45,630 --> 00:00:49,140 It gave us back a fixture, and that fixture object, 17 00:00:49,140 --> 00:00:50,793 it wrapped up the component. 18 00:00:51,630 --> 00:00:56,280 The component enabled us to write tests like this. 19 00:00:56,280 --> 00:00:58,080 So, that was the headercomponent. 20 00:00:58,080 --> 00:01:01,440 And that we ran the tests, and tests looked like this. 21 00:01:01,440 --> 00:01:04,830 The headercomponent was created successfully. 22 00:01:04,830 --> 00:01:09,830 But, also notice, the appcomponent also had some tests. 23 00:01:10,170 --> 00:01:11,910 So what, what we're gonna do 24 00:01:11,910 --> 00:01:14,130 in this section is have a look at the, the tests 25 00:01:14,130 --> 00:01:17,160 for the appcomponent and understand what's going on. 26 00:01:17,160 --> 00:01:19,088 Okay. So let's go back 27 00:01:19,088 --> 00:01:21,300 into the source code and for the appcomponent. 28 00:01:21,300 --> 00:01:23,580 I think the first place to start would be to look 29 00:01:23,580 --> 00:01:26,557 at the actual code for the appcomponent. 30 00:01:27,463 --> 00:01:30,030 Okay. So let's have a look in there, my appcomponent. 31 00:01:30,030 --> 00:01:33,870 So first of all, it is a class and it does have data. 32 00:01:33,870 --> 00:01:34,703 The purpose, 33 00:01:34,703 --> 00:01:37,710 in fact, there were two purposes for, for component class. 34 00:01:37,710 --> 00:01:40,560 One is to have data to be displayed. 35 00:01:40,560 --> 00:01:42,540 And the other thing is to handle events 36 00:01:42,540 --> 00:01:44,460 from its HTML template 37 00:01:44,460 --> 00:01:47,730 because every component has an HTML template 38 00:01:47,730 --> 00:01:51,810 to display the data and to generate events. 39 00:01:51,810 --> 00:01:54,948 So, let's have a look at the HTML file to see how 40 00:01:54,948 --> 00:01:57,780 it displays this type of property. 41 00:01:57,780 --> 00:02:00,090 This is the HTM template, 42 00:02:00,090 --> 00:02:03,300 and it says, whatever the title was, 43 00:02:03,300 --> 00:02:05,460 what was the title actually? 44 00:02:05,460 --> 00:02:07,365 The title was HelloWorld. 45 00:02:07,365 --> 00:02:08,198 Of course it was. 46 00:02:08,198 --> 00:02:10,410 HelloWorld is the title property. 47 00:02:10,410 --> 00:02:15,390 So data binding, grab the value of title from the component. 48 00:02:15,390 --> 00:02:18,210 HelloWorld app is running. 49 00:02:18,210 --> 00:02:21,450 Also, it instantly did my headercomponent 50 00:02:21,450 --> 00:02:23,250 that we just looked at. 51 00:02:23,250 --> 00:02:26,160 Okay, so that's simple enough. 52 00:02:26,160 --> 00:02:27,860 Now let's have a look at the spec. 53 00:02:29,228 --> 00:02:31,128 So this is the spec that was generated 54 00:02:32,597 --> 00:02:34,290 by angular CLI, I haven't embellished this. 55 00:02:34,290 --> 00:02:37,710 This was actually generated by the angular CLI tool. 56 00:02:37,710 --> 00:02:40,980 So from the top import the test bed class 57 00:02:40,980 --> 00:02:45,180 from Angular core testing, the test bed is kind of like, 58 00:02:45,180 --> 00:02:46,440 it enables us to create a 59 00:02:46,440 --> 00:02:51,393 a dummy module that contains our components for testing. 60 00:02:52,380 --> 00:02:55,260 Before each test, there were three different tests here. 61 00:02:55,260 --> 00:02:58,440 As you can see online, 14, 20, and 26. 62 00:02:58,440 --> 00:03:00,180 There were three tests. 63 00:03:00,180 --> 00:03:01,230 We kind of knew that anyway 64 00:03:01,230 --> 00:03:03,030 because there were three tests here. 65 00:03:04,650 --> 00:03:07,743 Before each of those tests, it executes this code. 66 00:03:09,390 --> 00:03:12,060 It asks the testbed to create a testing 67 00:03:12,060 --> 00:03:16,050 module that knows about our component. 68 00:03:16,050 --> 00:03:18,690 Okay. So when that component has been loaded 69 00:03:18,690 --> 00:03:22,650 into the test model, compile that component. 70 00:03:22,650 --> 00:03:24,780 So, remember what that function does. 71 00:03:24,780 --> 00:03:27,330 Each component has an HTML template 72 00:03:27,330 --> 00:03:29,940 but that HTML template actually gets compiled 73 00:03:29,940 --> 00:03:32,550 or converted into pure JavaScript. 74 00:03:32,550 --> 00:03:34,920 So this is what would normally happen 75 00:03:34,920 --> 00:03:37,470 doing compilation, that's what's happening here. 76 00:03:37,470 --> 00:03:39,810 It basically converts the HTML 77 00:03:39,810 --> 00:03:42,393 into pure JavaScript to be executed. 78 00:03:43,230 --> 00:03:46,800 So by this, at this point, now the testbed now 79 00:03:46,800 --> 00:03:51,480 has created a module that knows about my appcomponent. 80 00:03:51,480 --> 00:03:53,700 Okay. So it'll, recreate, 81 00:03:53,700 --> 00:03:55,503 it'll do that before each test. 82 00:03:56,768 --> 00:03:59,370 And the first test, it goes to the testbed. 83 00:03:59,370 --> 00:04:02,190 Please create an instance of appcomponent. 84 00:04:02,190 --> 00:04:04,980 Remember we get back a fixture object 85 00:04:04,980 --> 00:04:07,440 and the fixture object is a wrapper 86 00:04:07,440 --> 00:04:08,493 to the component. 87 00:04:10,107 --> 00:04:11,970 So this here is the appcomponent 88 00:04:11,970 --> 00:04:15,368 and we can verify did the appcomponent, 89 00:04:15,368 --> 00:04:16,830 does the app component exist? 90 00:04:16,830 --> 00:04:19,083 The appcomponent should exist. 91 00:04:19,960 --> 00:04:20,793 Okay. And it does. 92 00:04:20,793 --> 00:04:23,650 Okay, so should create the app, the order 93 00:04:23,650 --> 00:04:26,310 in which you see these tests being displayed 94 00:04:26,310 --> 00:04:29,105 to you isn't necessarily the order 95 00:04:29,105 --> 00:04:31,770 in which they appear in the script, should create the app. 96 00:04:31,770 --> 00:04:34,260 That's the first test done. 97 00:04:34,260 --> 00:04:36,000 What about the second test? 98 00:04:36,000 --> 00:04:39,630 The application component should have the title. HelloWorld. 99 00:04:39,630 --> 00:04:42,090 What we're establishing here is, 100 00:04:42,090 --> 00:04:44,490 does my component have a title, 101 00:04:44,490 --> 00:04:47,370 Is an object, does it have a title property? 102 00:04:47,370 --> 00:04:48,824 HelloWorld. 103 00:04:48,824 --> 00:04:49,740 That's what this test does. 104 00:04:49,740 --> 00:04:51,870 Let's see how this works. 105 00:04:51,870 --> 00:04:56,870 So again, create the component, gives us back a fixture. 106 00:04:58,050 --> 00:05:01,650 That fixture is a wrapper to the component 107 00:05:01,650 --> 00:05:02,790 gives us back the component. 108 00:05:02,790 --> 00:05:06,090 That is an instance of my component class. 109 00:05:06,090 --> 00:05:09,964 App is basically the instance of my component. 110 00:05:09,964 --> 00:05:13,620 Okay? Check that the application object has a 111 00:05:13,620 --> 00:05:15,880 title equal to HelloWorld 112 00:05:16,830 --> 00:05:19,353 because that's the value that is in there. 113 00:05:20,190 --> 00:05:22,200 And it should be correct. 114 00:05:22,200 --> 00:05:25,410 Does my application component have a title property set 115 00:05:25,410 --> 00:05:26,490 to HelloWorld? 116 00:05:26,490 --> 00:05:28,470 It should have a title. 117 00:05:28,470 --> 00:05:30,030 HelloWorld. 118 00:05:30,030 --> 00:05:33,603 Let's have a look, and it worked. 119 00:05:34,440 --> 00:05:35,970 Good. 120 00:05:35,970 --> 00:05:37,710 What about the third test? 121 00:05:37,710 --> 00:05:39,030 The third test here. 122 00:05:39,030 --> 00:05:41,790 Oh, not only does it have a title property 123 00:05:41,790 --> 00:05:45,270 but it should render that title property correctly 124 00:05:45,270 --> 00:05:46,710 in the HTML. 125 00:05:46,710 --> 00:05:48,420 It's one thing for the component to 126 00:05:48,420 --> 00:05:51,420 have the right data, it's another thing to see 127 00:05:51,420 --> 00:05:53,730 if the HTML template rendered it properly, 128 00:05:53,730 --> 00:05:54,930 because it should have done. 129 00:05:54,930 --> 00:05:59,190 If my component has this title, then the HTML 130 00:05:59,190 --> 00:06:03,300 our HTML template should render it properly. 131 00:06:03,300 --> 00:06:04,950 It renders it as well, 132 00:06:04,950 --> 00:06:06,270 there should be something like 133 00:06:06,270 --> 00:06:08,430 HelloWorld app is running. 134 00:06:08,430 --> 00:06:10,932 Okay. There should be something that looks 135 00:06:10,932 --> 00:06:12,601 like that in the HTML. 136 00:06:12,601 --> 00:06:13,434 That's what we're testing for. 137 00:06:13,434 --> 00:06:14,610 So let's go back and have a look. 138 00:06:16,673 --> 00:06:19,050 Okay, so there's an element of repetition here. 139 00:06:19,050 --> 00:06:21,300 That statement seems to appear 140 00:06:21,300 --> 00:06:23,640 at the beginning of each test. 141 00:06:23,640 --> 00:06:26,160 So that could have been factored out actually into a 142 00:06:26,160 --> 00:06:27,600 before each. 143 00:06:27,600 --> 00:06:28,950 Anyway, create another instance 144 00:06:28,950 --> 00:06:32,850 of the component and give me back the fixture wrapper. 145 00:06:32,850 --> 00:06:37,800 Remember what the fixture detect changes statement does. 146 00:06:37,800 --> 00:06:40,050 The component has data. 147 00:06:40,050 --> 00:06:41,850 That data is gonna be displayed 148 00:06:41,850 --> 00:06:46,020 in the HTML template in order for that data binding to occur 149 00:06:46,020 --> 00:06:47,520 you've gotta call this function. 150 00:06:47,520 --> 00:06:51,270 Okay. So if you wanted to put a comment here. 151 00:06:51,270 --> 00:06:54,720 When you say fixture detect changes, what it means is, 152 00:06:54,720 --> 00:06:59,720 tell angular to do data binding. 153 00:07:01,980 --> 00:07:02,883 In other words, 154 00:07:05,460 --> 00:07:07,810 in other words, the HTML 155 00:07:09,594 --> 00:07:10,690 is updated 156 00:07:13,410 --> 00:07:17,853 with current data from the component. 157 00:07:19,830 --> 00:07:22,140 Okay? So basically it, it basically forces the 158 00:07:22,140 --> 00:07:24,720 angular engine to execute data binding. 159 00:07:24,720 --> 00:07:27,990 So in my HTML, when there's data binding here 160 00:07:27,990 --> 00:07:30,360 in order for that data binding to actually happen 161 00:07:30,360 --> 00:07:33,240 you have to say fixture detect changes. 162 00:07:33,240 --> 00:07:34,980 That's a really bad name for it, a better name 163 00:07:34,980 --> 00:07:37,020 would've been do data binding. 164 00:07:37,020 --> 00:07:41,910 Take the component and basically update the HTML 165 00:07:41,910 --> 00:07:43,710 with the current value of the title. 166 00:07:44,881 --> 00:07:48,090 So that should, after my detect changes function 167 00:07:48,090 --> 00:07:51,960 called that should now say, HelloWorld app is running. 168 00:07:51,960 --> 00:07:54,000 That's what should have happened. 169 00:07:54,000 --> 00:07:57,270 Okay, so now this is how you can actually check 170 00:07:57,270 --> 00:07:58,143 that it happened. 171 00:07:59,160 --> 00:08:01,860 You've got a fixture object 172 00:08:01,860 --> 00:08:04,650 and the fixture object points to the component. 173 00:08:04,650 --> 00:08:06,360 What you wanna do now is you wanna say 174 00:08:06,360 --> 00:08:08,310 look at the native HTML 175 00:08:08,310 --> 00:08:11,370 for that component to see what was actually rendered. 176 00:08:11,370 --> 00:08:14,910 And that's what this does, fixture native element. 177 00:08:14,910 --> 00:08:18,540 It says, go to my component and give me the, you know 178 00:08:18,540 --> 00:08:23,070 like the, the HTML inside that component from the, like the 179 00:08:23,070 --> 00:08:26,490 the top of the HTML, it gives you back an HTML element. 180 00:08:26,490 --> 00:08:29,970 Basically, the component that has been rendered as HTML 181 00:08:29,970 --> 00:08:31,680 it gives you back the HTML. 182 00:08:31,680 --> 00:08:33,240 When it says compiled here 183 00:08:33,240 --> 00:08:37,290 it means the HTML that has been generated effectively 184 00:08:37,290 --> 00:08:40,230 what HTML was generated here. 185 00:08:40,230 --> 00:08:44,550 It'll give you back pointer to the div effectively. 186 00:08:44,550 --> 00:08:46,230 Okay, so we can now say, 187 00:08:46,230 --> 00:08:48,540 we can now check the content of that div to say 188 00:08:48,540 --> 00:08:51,333 does it contain the right span, for example? 189 00:08:52,710 --> 00:08:56,790 So the native element, you get back basically pointer 190 00:08:56,790 --> 00:09:00,360 to the top of your, of your rendered content. 191 00:09:00,360 --> 00:09:04,230 So now we're in the kind of HTML sphere 192 00:09:04,230 --> 00:09:09,230 of influence take that rendered HTML and query selector. 193 00:09:09,900 --> 00:09:12,900 That's just a standard HTML five function, 194 00:09:12,900 --> 00:09:14,730 search in my HTML 195 00:09:14,730 --> 00:09:17,430 search for an element that has this property. 196 00:09:17,430 --> 00:09:22,293 I'm looking for an element that has a CSS class of content. 197 00:09:23,190 --> 00:09:24,960 And in that element 198 00:09:24,960 --> 00:09:27,620 there should be a descendant element called span. 199 00:09:27,620 --> 00:09:29,580 I'm looking for a span 200 00:09:29,580 --> 00:09:34,230 inside something with a CSS class of content. 201 00:09:34,230 --> 00:09:39,230 Okay, so that's gonna find, this here is an element 202 00:09:40,290 --> 00:09:45,090 with the CSS class of content and here's the span inside it. 203 00:09:45,090 --> 00:09:47,853 Okay. So that will basically find that span element. 204 00:09:49,800 --> 00:09:52,170 It could be null. 205 00:09:52,170 --> 00:09:54,240 So in type script 206 00:09:54,240 --> 00:09:57,240 the question mark is called the safe navigation operator. 207 00:09:57,240 --> 00:10:01,050 It says as long as that isn't kind of null or undefined. 208 00:10:01,050 --> 00:10:02,760 In other words, if it existed 209 00:10:02,760 --> 00:10:06,330 give me the text content of that span. 210 00:10:06,330 --> 00:10:09,188 So that will obviously give you the text content, 211 00:10:09,188 --> 00:10:11,490 after having been data bound. 212 00:10:11,490 --> 00:10:14,250 So it'll say, HelloWorld app is running. 213 00:10:14,250 --> 00:10:17,100 That's the text that we get back inside the span. 214 00:10:17,100 --> 00:10:18,850 This is starting to take shape now. 215 00:10:20,280 --> 00:10:21,780 Let's check that content. 216 00:10:21,780 --> 00:10:25,680 That content should contain this text. 217 00:10:25,680 --> 00:10:27,423 HelloWorld app is running. 218 00:10:28,320 --> 00:10:31,260 Okay, so from the top 219 00:10:31,260 --> 00:10:35,070 create the component, update data binding 220 00:10:35,070 --> 00:10:38,670 so the HTML is updated with the correct data. 221 00:10:38,670 --> 00:10:42,510 Give me back that content of the component as HTML. 222 00:10:42,510 --> 00:10:45,600 And then inside that HTML search for sub content, 223 00:10:45,600 --> 00:10:50,220 find the div as it happens with the CSS class of content, 224 00:10:50,220 --> 00:10:54,810 find the descendant element, the span, get its text content 225 00:10:54,810 --> 00:10:59,310 and verify that it contains HelloWorld app is running. 226 00:10:59,310 --> 00:11:03,510 And it does indeed to say, HelloWorld app is running. 227 00:11:03,510 --> 00:11:06,603 So when we run the tests, it all works beautifully. 228 00:11:07,439 --> 00:11:08,793 And that's that one there. 229 00:11:10,050 --> 00:11:12,210 So just to play devil's advocate 230 00:11:12,210 --> 00:11:15,540 I'm gonna deliberately break my HTML 231 00:11:15,540 --> 00:11:19,180 and I'm gonna change this to be is, is 232 00:11:20,520 --> 00:11:23,613 definitely running. 233 00:11:25,100 --> 00:11:27,390 Okay, so now the test will fail. 234 00:11:27,390 --> 00:11:29,890 That's the test of the span that we actually have. 235 00:11:30,780 --> 00:11:33,480 This is the text of the span it was looking for 236 00:11:33,480 --> 00:11:35,643 and it'll now fail this test. 237 00:11:38,249 --> 00:11:42,330 Okay, so it's failed the test in my app component suite. 238 00:11:42,330 --> 00:11:46,297 The test that failed should render title, 239 00:11:46,297 --> 00:11:48,240 that failed. 240 00:11:48,240 --> 00:11:50,493 In my test I was expecting this, 241 00:11:51,820 --> 00:11:53,890 well, that's basically what appeared 242 00:11:55,050 --> 00:11:57,423 and this is what I was hoping it did be, okay. 243 00:11:58,266 --> 00:11:59,099 So I can see what the problem is. 244 00:11:59,099 --> 00:12:01,110 I can see if there's a bug in my HTML 245 00:12:01,110 --> 00:12:05,820 let's fix the bug in my HTML, save it. 246 00:12:05,820 --> 00:12:07,620 It automatically reruns the test 247 00:12:07,620 --> 00:12:09,540 because it's running in watch mode. 248 00:12:09,540 --> 00:12:10,863 So that should now work. 249 00:12:12,009 --> 00:12:13,481 You just need to give it a moment 250 00:12:13,481 --> 00:12:14,314 and it's worked beautifully. 251 00:12:14,314 --> 00:12:15,980 Okay, so that's actually, you know, 252 00:12:15,980 --> 00:12:16,950 quite a realistic example 253 00:12:16,950 --> 00:12:18,840 of how to get started testing components. 254 00:12:18,840 --> 00:12:20,730 What we're gonna do in the next lesson is to 255 00:12:20,730 --> 00:12:23,400 dig a lot more into detail, to handle things 256 00:12:23,400 --> 00:12:26,601 like events and other features that you can have 257 00:12:26,601 --> 00:12:27,743 in an android application.