1 00:00:06,510 --> 00:00:08,970 - We've already seen in the last section 2 00:00:08,970 --> 00:00:11,910 how to define a spy on a function. 3 00:00:11,910 --> 00:00:15,600 You import a module that contains a function of interest 4 00:00:15,600 --> 00:00:17,640 and then you call jest.spy0n, 5 00:00:17,640 --> 00:00:20,370 you specify the module that contains the function, 6 00:00:20,370 --> 00:00:21,810 You specify the name of the function 7 00:00:21,810 --> 00:00:25,080 that you want the spy on, and you get back a spy. 8 00:00:25,080 --> 00:00:28,675 And this spy observes calls to that function. 9 00:00:28,675 --> 00:00:31,683 The function is still invoked as normal, 10 00:00:32,825 --> 00:00:36,360 and you just get a chance to observe 11 00:00:36,360 --> 00:00:38,730 how that function is invoked. 12 00:00:38,730 --> 00:00:40,950 You can take that a step further and as well 13 00:00:40,950 --> 00:00:44,850 as spying on that function to see, you know, was it invoked? 14 00:00:44,850 --> 00:00:48,480 You can actually define a mock implementation for a spy. 15 00:00:48,480 --> 00:00:51,105 So this is a combination of two things. 16 00:00:51,105 --> 00:00:55,740 This spy, this function already exists, what you want to do 17 00:00:55,740 --> 00:01:00,740 but maybe it has behavior that's unpredictable, 18 00:01:00,900 --> 00:01:03,240 like it returns a timestamp 19 00:01:03,240 --> 00:01:05,160 that you obviously can't predict. 20 00:01:05,160 --> 00:01:07,080 So if you want to, you can say, right 21 00:01:07,080 --> 00:01:08,880 I'm gonna create a spy on that function 22 00:01:08,880 --> 00:01:11,610 but not only am I going to spy on that function 23 00:01:11,610 --> 00:01:13,710 I'm going to re-implement that function 24 00:01:13,710 --> 00:01:15,084 with a mock behavior. 25 00:01:15,084 --> 00:01:19,350 Okay. So when you call spy on as well as saying, well 26 00:01:19,350 --> 00:01:22,110 instead of just saying, I'm going to spy on this function 27 00:01:22,110 --> 00:01:24,000 in this module, you can say, 28 00:01:24,000 --> 00:01:26,956 I'm going to spy on this function in this module 29 00:01:26,956 --> 00:01:30,030 and I'm going to replace its implementation 30 00:01:30,030 --> 00:01:31,143 with something else. 31 00:01:32,010 --> 00:01:35,340 So when the high level code calls someFunc, 32 00:01:35,340 --> 00:01:38,220 it'll actually call your mock implementation instead 33 00:01:38,220 --> 00:01:40,260 which presumably is hard-coded, 34 00:01:40,260 --> 00:01:42,480 and, um, more predictable. 35 00:01:42,480 --> 00:01:45,000 So you've replaced the original function 36 00:01:45,000 --> 00:01:46,770 with a mock implementation 37 00:01:46,770 --> 00:01:50,223 for deterministic behavior and simplicity. 38 00:01:51,390 --> 00:01:52,320 So we're gonna have a look 39 00:01:52,320 --> 00:01:56,790 at an example in the, in this folder: Mocking-SpyOn-Impl 40 00:01:56,790 --> 00:01:58,440 Again, if you wanna follow along, 41 00:01:59,700 --> 00:02:00,660 this is what it looks like. 42 00:02:00,660 --> 00:02:03,450 If you go into the Mocking-SpyOn-Impl folder, 43 00:02:03,450 --> 00:02:05,250 if you open that in the code editor, 44 00:02:06,840 --> 00:02:08,670 this is what it looks like. 45 00:02:08,670 --> 00:02:11,730 We have three levels of code from the top level 46 00:02:11,730 --> 00:02:14,610 we have high level code, and this is actually the same 47 00:02:14,610 --> 00:02:17,910 as the previous demo up to a point. 48 00:02:17,910 --> 00:02:19,710 So we have high level code 49 00:02:19,710 --> 00:02:23,550 with add, subtract, multiply, and divide operations. 50 00:02:23,550 --> 00:02:26,400 Those operations, called lower level operations 51 00:02:26,400 --> 00:02:31,200 in here to return informational, error or warning messages. 52 00:02:31,200 --> 00:02:33,840 And those functions rely on this module 53 00:02:33,840 --> 00:02:36,810 to get the current date and time as a time stamp. 54 00:02:36,810 --> 00:02:39,150 And this is what we're going to replace. 55 00:02:39,150 --> 00:02:41,492 We're gonna basically set up a spy on this, 56 00:02:41,492 --> 00:02:43,260 the function in here, 57 00:02:43,260 --> 00:02:46,280 so that instead of the real implementation, which returns 58 00:02:46,280 --> 00:02:49,440 to current date and time, which is who knows what that is. 59 00:02:49,440 --> 00:02:51,270 We're gonna mock that function 60 00:02:51,270 --> 00:02:52,873 with a hard-coded date and time. 61 00:02:52,873 --> 00:02:55,800 Okay? So that we know, effectively, 62 00:02:55,800 --> 00:02:58,380 what that date is gonna be when it returns. 63 00:02:58,380 --> 00:03:01,080 And that means we can write some higher level tests here 64 00:03:01,080 --> 00:03:02,070 that are more predictable. 65 00:03:02,070 --> 00:03:04,691 These tests here will call functions in here 66 00:03:04,691 --> 00:03:08,220 which get informational messages with the timestamp. 67 00:03:08,220 --> 00:03:09,840 We will mark that timestamp 68 00:03:09,840 --> 00:03:11,610 so that we know what it's gonna be. 69 00:03:11,610 --> 00:03:14,633 So in our tests, we can check more thoroughly 70 00:03:14,633 --> 00:03:16,410 what's going on. 71 00:03:16,410 --> 00:03:18,813 So let me show you how that fits together. 72 00:03:20,160 --> 00:03:22,050 We have high level code here, 73 00:03:22,050 --> 00:03:25,140 so I will call the add function, for example, 74 00:03:25,140 --> 00:03:27,780 those functions call lower level functions 75 00:03:27,780 --> 00:03:30,183 in the messaging module, messaging.js, 76 00:03:31,500 --> 00:03:33,210 like those, those functions. 77 00:03:33,210 --> 00:03:35,610 I'm not going to bother spying on those functions anymore 78 00:03:35,610 --> 00:03:38,370 because I presume that those functions work, 79 00:03:38,370 --> 00:03:42,540 but those functions, in turn, call that function 80 00:03:42,540 --> 00:03:44,610 and that's the function that I'm gonna spy on. 81 00:03:44,610 --> 00:03:47,520 I'm gonna define a spy or mock implementation 82 00:03:47,520 --> 00:03:50,370 that basically intercepts that function call 83 00:03:50,370 --> 00:03:53,760 and rather than just intercepting it and then calling it, 84 00:03:53,760 --> 00:03:55,350 it'll have a mock implementation. 85 00:03:55,350 --> 00:03:58,050 So the flow will be like this: 86 00:03:58,050 --> 00:04:01,800 In my test, I'll call one of these functions, 87 00:04:01,800 --> 00:04:05,280 like the divide function, the divide function, 88 00:04:05,280 --> 00:04:07,543 Well, well, it'll either call the info 89 00:04:07,543 --> 00:04:09,480 or the warn function depending 90 00:04:09,480 --> 00:04:11,820 on whether it's a divide by zero situation. 91 00:04:11,820 --> 00:04:15,603 So let's say it calls the info function like that. 92 00:04:16,680 --> 00:04:21,120 And the info function will call datetime nowString 93 00:04:21,120 --> 00:04:23,040 But instead of calling the, instead of calling 94 00:04:23,040 --> 00:04:25,560 the real version of nowString, 95 00:04:25,560 --> 00:04:30,510 instead, it'll call my kind of stubbed mock version instead. 96 00:04:30,510 --> 00:04:34,080 And this version, rather than returning the actual datetime 97 00:04:34,080 --> 00:04:36,750 it'll return the hard-coded datetime back. 98 00:04:36,750 --> 00:04:39,480 So we know exactly what string to expect back 99 00:04:39,480 --> 00:04:40,877 and we can test for it. 100 00:04:40,877 --> 00:04:44,640 That result will kind of permeate all the way back out here 101 00:04:44,640 --> 00:04:48,780 and all the way back out here and all the way back out here. 102 00:04:48,780 --> 00:04:51,210 So the, you know, the message we get back 103 00:04:51,210 --> 00:04:53,670 will have a well known datetime 104 00:04:53,670 --> 00:04:56,670 because I've hard-coded it in my module, 105 00:04:56,670 --> 00:04:59,883 in my function replacement there, in my mock function. 106 00:05:01,350 --> 00:05:05,340 Okay? So from the back to the front, 107 00:05:05,340 --> 00:05:06,870 here's my datetime.js, 108 00:05:06,870 --> 00:05:09,930 this is the real implementation, which I'm going to spy on 109 00:05:09,930 --> 00:05:13,344 and re-implement because it returns, 110 00:05:13,344 --> 00:05:17,040 it's very, it's impossible to test code 111 00:05:17,040 --> 00:05:18,630 that is based on dates and times 112 00:05:18,630 --> 00:05:22,410 because it's gonna be different every time you run the test. 113 00:05:22,410 --> 00:05:24,270 So if I did want to check, like, 114 00:05:24,270 --> 00:05:26,070 the string that eventually got built 115 00:05:26,967 --> 00:05:30,369 I've gotta do something about this because it's, you know 116 00:05:30,369 --> 00:05:33,330 it's gonna be unpredictable. 117 00:05:33,330 --> 00:05:34,950 So I'm going to, in my test, 118 00:05:34,950 --> 00:05:36,540 I'm going to re-implement this function. 119 00:05:36,540 --> 00:05:38,490 I'm gonna define a spy, 120 00:05:38,490 --> 00:05:39,870 and then I'm going to re-implement it 121 00:05:39,870 --> 00:05:41,700 with a hard-coded datetime. 122 00:05:41,700 --> 00:05:44,757 So this function actually won't be invoked. 123 00:05:44,757 --> 00:05:47,313 I'm gonna replace it with a mock implementation. 124 00:05:48,690 --> 00:05:52,500 In the code, if you look at it, 125 00:05:52,500 --> 00:05:56,910 just to verify it's exactly as I've just shown. 126 00:05:56,910 --> 00:05:59,730 Okay, so that function there does exist, 127 00:05:59,730 --> 00:06:01,380 but I'm going to kind of replace it. 128 00:06:01,380 --> 00:06:03,510 My spy will re-implement that function 129 00:06:03,510 --> 00:06:06,270 with a more predictable datetime string. 130 00:06:06,270 --> 00:06:08,820 Okay, so I call the nowString function 131 00:06:08,820 --> 00:06:10,020 for my messaging module. 132 00:06:10,020 --> 00:06:12,120 This is the second layer up, 133 00:06:12,120 --> 00:06:15,630 so I import my datetime module, that's this one here, 134 00:06:15,630 --> 00:06:18,990 the info function, it calls nowString. 135 00:06:18,990 --> 00:06:21,210 So if I didn't do anything else, 136 00:06:21,210 --> 00:06:24,503 this would be invoking that function there. 137 00:06:24,503 --> 00:06:28,481 Okay. But as we're gonna see, I'm gonna basically 138 00:06:28,481 --> 00:06:33,481 replace this function with a mock version. 139 00:06:33,600 --> 00:06:36,213 Okay. So it'll basically call in a mock version, 140 00:06:37,050 --> 00:06:40,470 and that mock version will return a hard-coded datetime, 141 00:06:40,470 --> 00:06:44,040 which I can predict because I've written that mock version. 142 00:06:44,040 --> 00:06:46,170 So our mock will replace, 143 00:06:46,170 --> 00:06:48,480 rather than it calling the original function like that, 144 00:06:48,480 --> 00:06:51,148 it'll call our mock implementation instead. 145 00:06:51,148 --> 00:06:52,648 And the same here, 146 00:06:53,492 --> 00:06:55,650 and the same here. 147 00:06:55,650 --> 00:06:58,000 In each case it'll call my mock implementation. 148 00:06:58,950 --> 00:07:02,670 So messaging.js is my, my kind of middle layer. 149 00:07:02,670 --> 00:07:06,120 The top layer in my demo is operations.js, 150 00:07:06,120 --> 00:07:08,610 We've seen this before, this is the same as before. 151 00:07:08,610 --> 00:07:11,940 When I call the add or subtract, multiply, or divide 152 00:07:11,940 --> 00:07:15,240 it calls one of those low level messaging functions, 153 00:07:15,240 --> 00:07:18,630 info, warning or error potentially. 154 00:07:18,630 --> 00:07:23,630 Okay. So let's see how to put the test together. 155 00:07:25,500 --> 00:07:27,180 This is my test code. 156 00:07:27,180 --> 00:07:29,913 So I import the messaging module, 157 00:07:31,140 --> 00:07:34,800 because I'm gonna potentially spy on the info function. 158 00:07:34,800 --> 00:07:39,450 I'm gonna spy on the info function to detect, you know, 159 00:07:39,450 --> 00:07:42,180 was that function invoked properly? 160 00:07:42,180 --> 00:07:44,670 I could also set up spies on the error 161 00:07:44,670 --> 00:07:46,370 and the warning functions as well. 162 00:07:47,447 --> 00:07:50,040 Okay. And then before each test, 163 00:07:50,040 --> 00:07:52,320 I'm gonna have multiple tests potentially, 164 00:07:52,320 --> 00:07:55,380 before each test I'm gonna create a new spy 165 00:07:55,380 --> 00:07:57,270 on the nowString function, 166 00:07:57,270 --> 00:08:00,240 but not only am I gonna spy on the nowString function, 167 00:08:00,240 --> 00:08:01,410 in my datetime module, 168 00:08:01,410 --> 00:08:03,390 I'm going to replace this implementation 169 00:08:03,390 --> 00:08:05,430 with a hard-coded implementation. 170 00:08:05,430 --> 00:08:09,390 Okay. So remember how this hangs together. 171 00:08:09,390 --> 00:08:11,670 The big picture is I have these kind of 172 00:08:11,670 --> 00:08:13,623 intermediate functions like info, 173 00:08:14,490 --> 00:08:15,453 and warn, 174 00:08:17,100 --> 00:08:17,933 and error, 175 00:08:19,350 --> 00:08:20,250 like that. 176 00:08:20,250 --> 00:08:22,890 When I call one of these functions, 177 00:08:22,890 --> 00:08:26,133 it will be trying to call the nowString function 178 00:08:26,133 --> 00:08:28,140 to give me back, you know, 179 00:08:28,140 --> 00:08:30,490 the current date and time, that says nowString, 180 00:08:31,590 --> 00:08:33,557 but what I'm doing here, 181 00:08:33,557 --> 00:08:35,970 is I'm replacing the nowString function 182 00:08:35,970 --> 00:08:37,560 with a mock implementation. 183 00:08:37,560 --> 00:08:42,560 So when info calls nowString, 184 00:08:43,170 --> 00:08:46,560 this basically is the replacement implementation 185 00:08:46,560 --> 00:08:47,433 for nowString. 186 00:08:48,300 --> 00:08:50,403 Okay? So that Lambda there, 187 00:08:53,040 --> 00:08:55,533 basically replaces that function there. 188 00:08:56,610 --> 00:08:59,220 The info function is gonna be calling, that is, 189 00:08:59,220 --> 00:09:01,650 the effective implementation of nowString. 190 00:09:01,650 --> 00:09:03,213 And it's hard-coded. 191 00:09:04,050 --> 00:09:08,190 It says, oh, it says 2021. 192 00:09:08,190 --> 00:09:11,160 It's the 3rd of December, which is my birthday. 193 00:09:11,160 --> 00:09:12,450 What a coincidence. 194 00:09:12,450 --> 00:09:17,450 at 8:00 AM, and 123 milliseconds. 195 00:09:17,520 --> 00:09:22,520 Okay. Zulu time, which means Greenwich Mean Time. 196 00:09:22,950 --> 00:09:25,440 So every time any function calls nowString, 197 00:09:25,440 --> 00:09:27,450 this is the function that'll actually be called, 198 00:09:27,450 --> 00:09:29,133 not the actual function instead. 199 00:09:30,750 --> 00:09:34,260 Remember also when you are, when you're setting up mocks 200 00:09:34,260 --> 00:09:39,260 like I've set up a mock on info and warn and error mocks, 201 00:09:39,270 --> 00:09:41,130 which can spies, sorry, 202 00:09:41,130 --> 00:09:43,800 which can kind of intercept calls to functions. 203 00:09:43,800 --> 00:09:47,220 So if you have a spy, excuse me, like that 204 00:09:47,220 --> 00:09:52,220 or a spy like this, you want to, for each test, 205 00:09:52,790 --> 00:09:56,670 you want to clear the information in those spies. 206 00:09:56,670 --> 00:09:59,190 Spies accumulate information about how many times 207 00:09:59,190 --> 00:10:00,630 was the info function called? 208 00:10:00,630 --> 00:10:02,820 How many times was the warning function called? 209 00:10:02,820 --> 00:10:04,890 And how many times was the error function called? 210 00:10:04,890 --> 00:10:07,770 You probably wanna reset those counters after each test. 211 00:10:07,770 --> 00:10:09,120 And that's what this does. 212 00:10:09,120 --> 00:10:11,070 When you call clearAllMocks, 213 00:10:11,070 --> 00:10:14,160 it resets all the information in your spies 214 00:10:14,160 --> 00:10:16,863 so that you can start from scratch for the next test. 215 00:10:17,850 --> 00:10:21,047 Okay. So just to confirm, before each test, 216 00:10:21,047 --> 00:10:24,270 we spy on the nowString function, 217 00:10:24,270 --> 00:10:26,910 and we tell it what it should return. 218 00:10:26,910 --> 00:10:29,836 After each test, we clear all the info 219 00:10:29,836 --> 00:10:33,240 that's been accrued by my spies, 220 00:10:33,240 --> 00:10:35,370 the counts of calls. 221 00:10:35,370 --> 00:10:37,560 So that's the beginning of my test code. 222 00:10:37,560 --> 00:10:38,640 I think it's probably worthwhile looking 223 00:10:38,640 --> 00:10:40,860 at the actual code in the demo. 224 00:10:40,860 --> 00:10:45,660 So this is my operations test. 225 00:10:45,660 --> 00:10:49,080 So I've set up a spy on the info function. 226 00:10:49,080 --> 00:10:50,370 And like I said, I could also set 227 00:10:50,370 --> 00:10:53,100 up a spy on the warn function and the error function, 228 00:10:53,100 --> 00:10:54,780 if I was interested. 229 00:10:54,780 --> 00:10:59,780 Before each test, mock the nowString function. 230 00:11:00,240 --> 00:11:03,603 After each test, clear all mock information. 231 00:11:05,550 --> 00:11:09,243 Okay. And then in here I've got a couple of tests. 232 00:11:12,983 --> 00:11:14,983 There we go, so I have three tests here. 233 00:11:15,900 --> 00:11:17,550 Let's have a look at those tests. 234 00:11:19,830 --> 00:11:21,719 Okay. This is a simple test. 235 00:11:21,719 --> 00:11:25,530 I'm just literally calling the nowString function. 236 00:11:25,530 --> 00:11:28,560 Well, that's the function that I just mocked. 237 00:11:28,560 --> 00:11:31,380 Okay. This, when I call nowString, 238 00:11:31,380 --> 00:11:34,710 that's going to, what that's actually going to invoke, 239 00:11:34,710 --> 00:11:36,450 is going to be this, 240 00:11:36,450 --> 00:11:40,170 is the mock implementation for nowString. 241 00:11:40,170 --> 00:11:41,790 So that's a, that's a simple test. 242 00:11:41,790 --> 00:11:43,740 When I call, whenever I call nowString, 243 00:11:43,740 --> 00:11:45,153 it should just return that. 244 00:11:46,903 --> 00:11:51,120 Okay. So in my first simple test, when I call nowString, 245 00:11:51,120 --> 00:11:53,760 the result that I get back should be that result. 246 00:11:53,760 --> 00:11:56,280 I get back there, should be the same 247 00:11:56,280 --> 00:11:57,630 as this result up here. 248 00:11:57,630 --> 00:11:59,136 I hadn't really proved anything, 249 00:11:59,136 --> 00:12:02,280 other than the fact as a proof of concept, 250 00:12:02,280 --> 00:12:05,772 that I have actually correctly mocked this function. 251 00:12:05,772 --> 00:12:06,900 And when I call that function, 252 00:12:06,900 --> 00:12:09,690 it will return the mock implementation 253 00:12:09,690 --> 00:12:10,830 as I've specified up here. 254 00:12:10,830 --> 00:12:12,120 So really at this point, 255 00:12:12,120 --> 00:12:15,690 I'm verifying that the mock implementation is in place. 256 00:12:15,690 --> 00:12:20,010 Okay. So here's a more ambitious example. 257 00:12:20,010 --> 00:12:22,410 What I'm doing now is I'm calling the info function. 258 00:12:22,410 --> 00:12:24,810 So again, remember what happens 259 00:12:24,810 --> 00:12:26,380 when you call the info function 260 00:12:27,420 --> 00:12:28,743 with some kind of message. 261 00:12:29,730 --> 00:12:31,110 The first thing that it does 262 00:12:31,110 --> 00:12:35,201 is to call the nowString function, which I've mocked. 263 00:12:35,201 --> 00:12:39,240 Okay. So rather than calling the nowString function, 264 00:12:39,240 --> 00:12:41,700 it should actually call the mock version 265 00:12:41,700 --> 00:12:44,280 which returns the hard-coded datetime. 266 00:12:44,280 --> 00:12:48,090 I think it was the 3rd of December, 2021. 267 00:12:48,090 --> 00:12:49,173 I remember it well. 268 00:12:50,310 --> 00:12:54,348 So when I call msg.info with Hi, 269 00:12:54,348 --> 00:12:57,820 what I should get back, what that function should return 270 00:12:59,190 --> 00:13:04,140 should be the timestamp, which should be 271 00:13:04,140 --> 00:13:07,260 2021, the 3rd of December, just after 8:00 AM 272 00:13:07,260 --> 00:13:09,480 with an info string and Hi. 273 00:13:09,480 --> 00:13:12,390 So what I verified here is that the, 274 00:13:12,390 --> 00:13:16,113 when I called info, that bit there, 275 00:13:20,880 --> 00:13:23,490 that bit there, came back from the call 276 00:13:23,490 --> 00:13:27,690 to the nowString function or rather the mock version of it. 277 00:13:27,690 --> 00:13:30,600 And the rest of it was actually what was generated 278 00:13:30,600 --> 00:13:33,330 by the info function itself. 279 00:13:33,330 --> 00:13:36,000 If you remember how the info function worked, 280 00:13:36,000 --> 00:13:40,660 as a quick reminder, my messaging module, when I call info 281 00:13:42,570 --> 00:13:44,520 it returns, inside square brackets, 282 00:13:44,520 --> 00:13:46,740 whatever the datetime stamp is, well 283 00:13:46,740 --> 00:13:49,830 that's the hard-coded datetime stamp info. 284 00:13:49,830 --> 00:13:51,993 And then whatever the message was, like Hi. 285 00:13:53,440 --> 00:13:54,900 Okay. So we're verifying 286 00:13:54,900 --> 00:13:58,830 that that was actually returned successfully, right. 287 00:13:58,830 --> 00:14:02,190 So I've run those tests, I've run them already. 288 00:14:02,190 --> 00:14:03,963 And they worked, which is great. 289 00:14:04,800 --> 00:14:06,993 And then I've got a more realistic test. 290 00:14:06,993 --> 00:14:09,210 This realistic test is actually kind of 291 00:14:09,210 --> 00:14:11,250 invoking the code from the top. 292 00:14:11,250 --> 00:14:14,636 So I call the divide function in my test. 293 00:14:14,636 --> 00:14:18,120 And when the divide function is invoked, 294 00:14:18,120 --> 00:14:21,540 as long as the denominator isn't zero, 295 00:14:21,540 --> 00:14:25,083 the divide function should call the info function. 296 00:14:27,436 --> 00:14:28,470 There it is. 297 00:14:28,470 --> 00:14:33,470 And remember, I set up a spy on the info function 298 00:14:34,470 --> 00:14:36,720 to make sure that it was actually invoked. 299 00:14:36,720 --> 00:14:41,253 Remember how I did that? In my test code. 300 00:14:42,540 --> 00:14:44,193 If I just get my test code up, 301 00:14:45,090 --> 00:14:47,970 at the top of my code here, I set up a spy on info. 302 00:14:47,970 --> 00:14:51,210 that'll tell me if the info function's called 303 00:14:51,210 --> 00:14:52,920 and when the info function's called, 304 00:14:52,920 --> 00:14:56,793 it, as we just discussed, it called the nowString function. 305 00:14:59,010 --> 00:15:02,697 nowString, okay, that's what that is, nowString. 306 00:15:02,697 --> 00:15:05,430 But of course, I've mocked that implementation now. 307 00:15:05,430 --> 00:15:07,230 So it doesn't actually call that function. 308 00:15:07,230 --> 00:15:09,660 It kind of calls my mock version instead, 309 00:15:09,660 --> 00:15:13,960 which returns the hard-coded 3rd of December date 310 00:15:14,910 --> 00:15:18,600 Feel free to send me gifts on the 3rd of December. 311 00:15:18,600 --> 00:15:20,790 So that's the scenario, this is what I'm testing. 312 00:15:20,790 --> 00:15:22,860 I'm calling the divide functions 313 00:15:22,860 --> 00:15:24,660 and I'm kind of testing it all the way through. 314 00:15:24,660 --> 00:15:26,283 So let's see what should happen. 315 00:15:27,690 --> 00:15:28,980 Right? So first of all, 316 00:15:28,980 --> 00:15:31,560 I call the high level function and the test 317 00:15:31,560 --> 00:15:33,240 which calls the info function, 318 00:15:33,240 --> 00:15:35,643 which calls the mocked nowString function. 319 00:15:37,380 --> 00:15:41,460 Verify that the info function was called 320 00:15:41,460 --> 00:15:42,450 with the correct parameter. 321 00:15:42,450 --> 00:15:46,653 So basically verify that this function was invoked there. 322 00:15:49,470 --> 00:15:51,780 I could also verify that the error function 323 00:15:51,780 --> 00:15:55,920 wasn't called and that the warning function wasn't called. 324 00:15:55,920 --> 00:15:57,650 Now, what about this info mock? 325 00:15:57,650 --> 00:16:00,600 If you remember from an earlier lesson, 326 00:16:00,600 --> 00:16:04,500 when you have a mock object, it has a mock property, 327 00:16:04,500 --> 00:16:06,930 and the mock property gives you information 328 00:16:06,930 --> 00:16:08,910 about how was that function called. 329 00:16:08,910 --> 00:16:11,700 This mock object here retains information 330 00:16:11,700 --> 00:16:13,980 about how that call happened. 331 00:16:13,980 --> 00:16:16,181 So I can say, give me information 332 00:16:16,181 --> 00:16:19,233 about how your function was invoked. 333 00:16:21,150 --> 00:16:24,420 How many times was it called? One. 334 00:16:24,420 --> 00:16:27,510 Okay. It was, there was just one result. 335 00:16:27,510 --> 00:16:29,433 It only called the info function once. 336 00:16:30,300 --> 00:16:32,610 So give me the result that it gave back. 337 00:16:32,610 --> 00:16:35,463 What was the result that the info function returned? 338 00:16:36,300 --> 00:16:38,190 So go into the mock object, 339 00:16:38,190 --> 00:16:40,560 but just kind of this then here, really, 340 00:16:40,560 --> 00:16:43,650 give me result zero, give me the value of result zero. 341 00:16:43,650 --> 00:16:47,200 So in other words, what value did that function return 342 00:16:48,060 --> 00:16:50,190 back to the divide function? 343 00:16:50,190 --> 00:16:52,440 I can intercept that return value here 344 00:16:52,440 --> 00:16:53,640 and that's what I've done. 345 00:16:53,640 --> 00:16:56,161 And the return value should have been, well, the timestamp 346 00:16:56,161 --> 00:16:59,040 which I know is hard-coded, 347 00:16:59,040 --> 00:17:03,120 plus an info message, plus whatever was passed in. 348 00:17:03,120 --> 00:17:06,510 So if you go back and look at how the info function works, 349 00:17:06,510 --> 00:17:09,360 it displays a timestamp, it displays an info, 350 00:17:09,360 --> 00:17:12,750 and then it displays whatever message you passed in. 351 00:17:12,750 --> 00:17:15,123 Okay, like that, in divide. 352 00:17:16,020 --> 00:17:18,333 So that's actually quite a thorough test, 353 00:17:19,530 --> 00:17:22,950 I can run it, and cross fingers it works, 354 00:17:22,950 --> 00:17:26,040 well I've actually run it already, and it works. 355 00:17:26,040 --> 00:17:28,470 So there we go, so you can spy on a function, 356 00:17:28,470 --> 00:17:30,090 to observe if it was called. 357 00:17:30,090 --> 00:17:31,620 You can also spy on a function 358 00:17:31,620 --> 00:17:33,510 and replace its implementation, 359 00:17:33,510 --> 00:17:35,671 so that, you know, tests can be implemented 360 00:17:35,671 --> 00:17:38,883 in a more deterministic manner.