1 00:00:00,090 --> 00:00:06,300 In this lecture, we are going to talk about mocking one aspect of unit testing is isolating a component. 2 00:00:06,330 --> 00:00:10,230 Ideally, the more isolated a component, the better the test. 3 00:00:10,230 --> 00:00:14,060 However, isolating a component is easier said than done. 4 00:00:14,070 --> 00:00:16,710 Components may require dependencies. 5 00:00:16,710 --> 00:00:22,410 For example, the tabs container component had a dependency on the tab component. 6 00:00:22,440 --> 00:00:27,150 Therefore we had to register two components with our testing module. 7 00:00:27,180 --> 00:00:29,370 This situation is not uncommon. 8 00:00:29,370 --> 00:00:34,110 You can't proceed with your tests until all dependencies have been resolved. 9 00:00:34,110 --> 00:00:39,810 However, what if our dependencies have other dependencies the problem can easily compound. 10 00:00:39,810 --> 00:00:42,870 Thus testing can quickly become a nightmare. 11 00:00:42,870 --> 00:00:45,960 For this reason, there's a concept called mocking. 12 00:00:45,960 --> 00:00:49,290 Mocking is the process of creating a fake dependency. 13 00:00:49,290 --> 00:00:53,280 By faking and dependency, our components can behave normally. 14 00:00:53,280 --> 00:00:59,580 Faking a dependency will allow us to isolate the component and worry about one less thing during a test. 15 00:00:59,580 --> 00:01:02,940 The question becomes When should we mock a dependency? 16 00:01:02,940 --> 00:01:07,950 Like I said before, unit testing should focus on a single class or component. 17 00:01:07,980 --> 00:01:12,180 If a dependency is not necessary for a test, we should mock it. 18 00:01:14,210 --> 00:01:18,190 We're going to write one final unit test in my editor. 19 00:01:18,200 --> 00:01:21,590 I'm viewing the navigation component template file. 20 00:01:21,620 --> 00:01:25,760 You should open this file in your editor to the navigation component. 21 00:01:25,760 --> 00:01:29,420 We'll display links in the header before it renders links. 22 00:01:29,420 --> 00:01:33,380 It'll check for the user's authentication status in the template. 23 00:01:33,380 --> 00:01:39,020 Let's scroll to the primary navigation on the first list item element. 24 00:01:39,020 --> 00:01:41,450 We're conditionally rendering this link. 25 00:01:41,450 --> 00:01:45,440 The condition is an observable called is authenticated. 26 00:01:45,470 --> 00:01:49,220 This observable image, the user's authentication status. 27 00:01:49,220 --> 00:01:52,310 If they're not logged in, this link will get rendered. 28 00:01:52,340 --> 00:01:57,050 Otherwise the links in the template element will be rendered. 29 00:01:57,050 --> 00:02:00,140 Our test will force the user to be logged in. 30 00:02:00,140 --> 00:02:03,350 The components template should respond accordingly. 31 00:02:03,350 --> 00:02:07,340 The links from the IMG template element should be available. 32 00:02:07,340 --> 00:02:10,460 We're going to perform a query for these links. 33 00:02:10,460 --> 00:02:14,120 Specifically, we're going to query the logout link. 34 00:02:14,120 --> 00:02:17,300 After selecting this element, we will click the link. 35 00:02:17,330 --> 00:02:22,520 If we're able to perform these actions, we can consider our test a success. 36 00:02:22,550 --> 00:02:23,870 Let's get started. 37 00:02:23,870 --> 00:02:28,790 First, we must rename the test file in the same directory as the template. 38 00:02:28,790 --> 00:02:33,950 Rename the navigation test file by removing the broken extension. 39 00:02:36,150 --> 00:02:40,400 After renaming the file, the server should pick up on our test file. 40 00:02:40,410 --> 00:02:43,740 Let's head over to the browser to check out the results. 41 00:02:45,870 --> 00:02:48,800 The test for creating a component has failed. 42 00:02:48,810 --> 00:02:51,090 Let's read the error message together. 43 00:02:51,120 --> 00:02:58,800 No provider for injection token angular fire error component relies on the authentication service for 44 00:02:58,800 --> 00:03:01,470 checking the user's authentication status. 45 00:03:01,470 --> 00:03:06,720 This service relies on the angular fire package to send a request to our back end. 46 00:03:06,720 --> 00:03:10,410 In a sense, our dependency has another dependency. 47 00:03:10,440 --> 00:03:15,420 Our service will not work without this package being rendered with the testing module. 48 00:03:15,450 --> 00:03:18,000 However, we don't care about our back end. 49 00:03:18,000 --> 00:03:20,970 We don't even care about the authentication service. 50 00:03:20,970 --> 00:03:27,300 The goal of our test is to check that the template renders a set of links for logging users as long 51 00:03:27,300 --> 00:03:29,700 as the service emits a true value. 52 00:03:29,730 --> 00:03:31,650 The service has done its job. 53 00:03:31,650 --> 00:03:32,880 In my opinion. 54 00:03:32,880 --> 00:03:37,680 Rather than configuring Firebase for our tests, we should mock the service. 55 00:03:37,680 --> 00:03:40,890 It'll be easier, faster and more reliable. 56 00:03:40,890 --> 00:03:42,450 Head back to the editor. 57 00:03:42,570 --> 00:03:47,580 Jazmin has a function for creating mocks inside the described function. 58 00:03:47,610 --> 00:03:51,240 Create a variable called mocked off service. 59 00:03:51,240 --> 00:03:57,060 The value for this variable will be the jasmine dot create spi object function. 60 00:03:59,250 --> 00:04:02,860 The Create SPI object function will create an object. 61 00:04:02,880 --> 00:04:07,920 The question is why are we using this function instead of creating a regular object? 62 00:04:07,950 --> 00:04:12,730 Unlike a regular object, Jasmin will spy on the methods of this object. 63 00:04:12,750 --> 00:04:14,850 The idea of spying is simple. 64 00:04:14,880 --> 00:04:18,360 A spy will count the number of times the method has been called. 65 00:04:18,360 --> 00:04:20,620 But why would we need this information? 66 00:04:20,640 --> 00:04:27,600 The logout link from the template should call the logout method from the authentication service, otherwise 67 00:04:27,600 --> 00:04:29,790 the user will not be logged out. 68 00:04:29,820 --> 00:04:36,570 Our test should verify that our component calls the correct method for logging user out of the application. 69 00:04:36,570 --> 00:04:39,840 Without a spy, we can't verify this behavior. 70 00:04:39,840 --> 00:04:43,130 If that doesn't make sense, that's perfectly fine. 71 00:04:43,140 --> 00:04:45,450 You'll see a code example in a moment. 72 00:04:45,480 --> 00:04:48,060 This function has three arguments. 73 00:04:48,060 --> 00:04:51,470 The first argument is the name of the object to mock. 74 00:04:51,480 --> 00:04:56,220 In our case, the dependency is the authentication service class. 75 00:04:58,540 --> 00:05:01,420 The second argument is an array of methods. 76 00:05:01,450 --> 00:05:06,250 Our service has two methods called create user and log outs. 77 00:05:08,450 --> 00:05:13,580 As you can see, we don't have to create the complete logic for our marked service. 78 00:05:13,580 --> 00:05:18,160 The Create SPI object function will handle the implementation details. 79 00:05:18,170 --> 00:05:21,260 The last argument is an object of properties. 80 00:05:21,290 --> 00:05:26,300 Our service has a few properties, however, most of them aren't relevant. 81 00:05:26,330 --> 00:05:31,910 The most important property is the is authenticated dollar sign property. 82 00:05:31,910 --> 00:05:35,030 This is the most important property from our service. 83 00:05:35,030 --> 00:05:39,860 It's an observable that will emit the user's authentication status as a boolean. 84 00:05:39,860 --> 00:05:46,310 Rather than using Firebase to create this observable, let's create an observable that will always emit 85 00:05:46,310 --> 00:05:48,590 true at the top of the file. 86 00:05:48,590 --> 00:05:52,670 Import the of operator from the JS package. 87 00:05:54,700 --> 00:06:02,590 Back in the mock object set the is authenticated property to the of operator in this operator pass in 88 00:06:02,590 --> 00:06:03,190 true. 89 00:06:05,400 --> 00:06:09,470 Mocking the service will give us complete control over the observable. 90 00:06:09,480 --> 00:06:15,780 Rather than waiting for the service to send a request, we can change the observable to always emit 91 00:06:15,780 --> 00:06:16,510 true. 92 00:06:16,530 --> 00:06:22,030 By doing so, we're forcing the user to be logged in creating a mocked service. 93 00:06:22,050 --> 00:06:26,190 It's faster than connecting to Firebase and importing the dependencies. 94 00:06:26,220 --> 00:06:28,550 Our mark is ready in the next lecture. 95 00:06:28,560 --> 00:06:31,740 Let's inject this service into our module.