1 00:00:06,510 --> 00:00:08,820 - Have a look at this example 2 00:00:08,820 --> 00:00:12,240 in the mocking rest calls demo folder. 3 00:00:12,240 --> 00:00:13,948 I've got a rest client 4 00:00:13,948 --> 00:00:16,650 which is going to invoke a rest service, 5 00:00:16,650 --> 00:00:19,620 a hypothetical rest service on my server. 6 00:00:19,620 --> 00:00:23,700 So it's similar code to what we saw in the previous section, 7 00:00:23,700 --> 00:00:25,170 but I'll just remind you, 8 00:00:25,170 --> 00:00:27,630 there might end up some kind back end server, 9 00:00:27,630 --> 00:00:29,910 a rest service at the back end. 10 00:00:29,910 --> 00:00:32,550 And what I've implemented here is a rest client. 11 00:00:32,550 --> 00:00:34,893 So I'm gonna draw that kind of here. 12 00:00:37,594 --> 00:00:40,623 Here's my rest client. 13 00:00:41,880 --> 00:00:43,680 And it provides an API. 14 00:00:43,680 --> 00:00:46,260 It provides a method to get all products. 15 00:00:46,260 --> 00:00:49,170 So there's my get all products function. 16 00:00:49,170 --> 00:00:50,280 Okay. 17 00:00:50,280 --> 00:00:53,370 And when I call that function, 18 00:00:53,370 --> 00:00:55,920 it's going to use Axios to interact 19 00:00:55,920 --> 00:00:57,270 with the rest service at the back end. 20 00:00:57,270 --> 00:00:59,970 So I've imported the Axios library. 21 00:00:59,970 --> 00:01:02,790 Let's imagine this is the URL of my rest service 22 00:01:02,790 --> 00:01:04,860 over there on the back end. 23 00:01:04,860 --> 00:01:06,930 So when I wanna get all products, 24 00:01:06,930 --> 00:01:08,640 I say using my Axios library. 25 00:01:08,640 --> 00:01:11,970 So imagine that Axios is kind of sitting here. 26 00:01:11,970 --> 00:01:13,830 What we're gonna do in this section 27 00:01:13,830 --> 00:01:17,670 is we're gonna basically mock the Axios layer itself. 28 00:01:17,670 --> 00:01:19,800 Okay, we're gonna basically create a mock 29 00:01:19,800 --> 00:01:21,003 of this layer here. 30 00:01:22,620 --> 00:01:24,450 Okay, so that's the objective. 31 00:01:24,450 --> 00:01:29,070 So in terms of that, Axios has got functions like get 32 00:01:29,070 --> 00:01:30,540 and post 33 00:01:30,540 --> 00:01:31,770 and put 34 00:01:31,770 --> 00:01:32,850 and delete. 35 00:01:32,850 --> 00:01:34,740 So I call the Axios get function. 36 00:01:34,740 --> 00:01:37,380 I pass in the URL to get all products. 37 00:01:37,380 --> 00:01:40,140 So my function here get all products, 38 00:01:40,140 --> 00:01:42,690 it calls the get function there. 39 00:01:42,690 --> 00:01:45,150 And what the get function does as you probably know 40 00:01:45,150 --> 00:01:46,560 is it returns a promise. 41 00:01:46,560 --> 00:01:49,372 So when I call the get function on Axios, 42 00:01:49,372 --> 00:01:52,390 it returns immediately with a promise object 43 00:01:53,850 --> 00:01:56,010 and that promise object will eventually contain the result 44 00:01:56,010 --> 00:01:58,290 from the rest service eventually. 45 00:01:58,290 --> 00:02:02,400 So when that result comes back eventually 46 00:02:02,400 --> 00:02:03,570 and what actually comes back, 47 00:02:03,570 --> 00:02:07,140 what you actually get back from the get function, 48 00:02:07,140 --> 00:02:08,100 haven't talked about this before, 49 00:02:08,100 --> 00:02:12,649 it's actually an object with the complete http response. 50 00:02:12,649 --> 00:02:16,710 One property in there is data. 51 00:02:16,710 --> 00:02:18,930 That's the actual result that you wanted to get back. 52 00:02:18,930 --> 00:02:22,060 So in our case, that's probably gonna be a bunch of products 53 00:02:23,040 --> 00:02:24,900 like that, okay? 54 00:02:24,900 --> 00:02:28,830 But there are other properties as well in the response, 55 00:02:28,830 --> 00:02:31,650 which kind of described the header, status code, headers, 56 00:02:31,650 --> 00:02:33,270 and such like, and so on. 57 00:02:33,270 --> 00:02:36,780 So this response that we get back from the get function, 58 00:02:36,780 --> 00:02:38,910 this response here, which we eventually get back 59 00:02:38,910 --> 00:02:40,809 when the promise is resolved, 60 00:02:40,809 --> 00:02:45,780 that is the entire http response effectively. 61 00:02:45,780 --> 00:02:47,910 What we then do is we say well, 62 00:02:47,910 --> 00:02:49,830 actually I'm not interested in the entire response, 63 00:02:49,830 --> 00:02:51,900 I'm just interested in the data part. 64 00:02:51,900 --> 00:02:54,630 So we then extract the data part, okay? 65 00:02:54,630 --> 00:02:58,050 And that data is basically what the user 66 00:02:58,050 --> 00:02:59,700 is interested in getting back, okay? 67 00:02:59,700 --> 00:03:01,413 Like the array of products. 68 00:03:03,450 --> 00:03:04,283 Okay. 69 00:03:04,283 --> 00:03:06,510 So how are we gonna, oh, and by the way 70 00:03:06,510 --> 00:03:09,840 I've got another function here, get product by ID, 71 00:03:09,840 --> 00:03:13,170 similar idea, get product by ID. 72 00:03:13,170 --> 00:03:15,750 When I call that function for my code, 73 00:03:15,750 --> 00:03:18,010 again it calls a get function 74 00:03:19,080 --> 00:03:21,993 but with a particular ID appended to the URL. 75 00:03:23,400 --> 00:03:25,320 So they'll send in a get request. 76 00:03:25,320 --> 00:03:26,670 The response that gets back this time, 77 00:03:26,670 --> 00:03:29,940 the data will just be one product, not all products. 78 00:03:29,940 --> 00:03:32,460 So if you wanna have a look at all of that code for yourself 79 00:03:32,460 --> 00:03:33,573 in the demo pack, 80 00:03:34,740 --> 00:03:37,200 you go to mocking rest calls 81 00:03:37,200 --> 00:03:40,020 and go into rest client dot JS, okay? 82 00:03:40,020 --> 00:03:42,900 That's the code that I've just been through. 83 00:03:42,900 --> 00:03:46,020 So what we're gonna look at now is how can I test 84 00:03:46,020 --> 00:03:47,283 my rest API? 85 00:03:48,388 --> 00:03:50,070 Well, how can I test it? 86 00:03:50,070 --> 00:03:52,170 Because really it's a problem because it's gonna, 87 00:03:52,170 --> 00:03:54,270 when I call this function for my test, 88 00:03:54,270 --> 00:03:57,360 it's going to start doing Axios-related stuff. 89 00:03:57,360 --> 00:03:59,520 So what I'm gonna do is I'm gonna, 90 00:03:59,520 --> 00:04:01,620 in my test I will test that function, 91 00:04:01,620 --> 00:04:06,240 but I'll mock the Axios get method or the Axios put method 92 00:04:06,240 --> 00:04:09,030 or the a Axios delete method, okay? 93 00:04:09,030 --> 00:04:12,900 So I'm going to mock Axios 94 00:04:12,900 --> 00:04:15,150 and have pretend versions of those functions 95 00:04:15,150 --> 00:04:18,480 that don't actually do a proper rest call. 96 00:04:18,480 --> 00:04:19,713 So let's do that now. 97 00:04:20,836 --> 00:04:22,196 All right. 98 00:04:22,196 --> 00:04:25,110 So to mock the Axios model, 99 00:04:25,110 --> 00:04:28,356 so first of all, in my test harness, 100 00:04:28,356 --> 00:04:30,870 I input the Axios library 101 00:04:30,870 --> 00:04:33,556 obviously because there were functions in there 102 00:04:33,556 --> 00:04:34,920 like get and put and post and delete, 103 00:04:34,920 --> 00:04:37,440 and I mock the entire Axio module. 104 00:04:37,440 --> 00:04:40,230 So I've just created or rather jest has created 105 00:04:40,230 --> 00:04:44,550 mock versions of Axios get, put, post, delete 106 00:04:44,550 --> 00:04:47,913 and other functions that might exist in the Axios module. 107 00:04:48,929 --> 00:04:50,670 I've got mock versions of all those functions. 108 00:04:50,670 --> 00:04:55,167 And remember, when you mock a module each mock function 109 00:04:55,167 --> 00:04:59,670 is kind of an empty implementation and it is is undefined 110 00:04:59,670 --> 00:05:01,113 as a starting point. 111 00:05:02,070 --> 00:05:03,390 Okay. 112 00:05:03,390 --> 00:05:06,607 So let's press on, let's have a look at how to actually call 113 00:05:06,607 --> 00:05:10,650 one of my rest functions mock in Axios. 114 00:05:10,650 --> 00:05:14,490 So just a quick reminder of what we're trying to do 115 00:05:14,490 --> 00:05:19,490 We had our, we had the Axios module at the back end. 116 00:05:19,500 --> 00:05:22,473 Axios module had functions such as get, 117 00:05:23,820 --> 00:05:26,220 okay, and post and put and delete. 118 00:05:26,220 --> 00:05:28,740 I've mocked that function and by default, 119 00:05:28,740 --> 00:05:31,770 that mock function would return undefined. 120 00:05:31,770 --> 00:05:33,900 Okay, so I'm gonna mock it. 121 00:05:33,900 --> 00:05:36,360 I've actually set up some sample data here. 122 00:05:36,360 --> 00:05:37,650 Let's have a look at the full code 123 00:05:37,650 --> 00:05:40,050 to see what that looks like. 124 00:05:40,050 --> 00:05:41,763 So this is rest client. 125 00:05:43,260 --> 00:05:46,950 So I've set up some ski-related products. 126 00:05:46,950 --> 00:05:51,647 That's going to be my sample data for mock purposes. 127 00:05:51,647 --> 00:05:54,226 So that's the sample data that we'll assume 128 00:05:54,226 --> 00:05:56,580 is the starting point. 129 00:05:56,580 --> 00:05:58,770 Okay, so that's there basically. 130 00:05:58,770 --> 00:06:01,290 I'm going to mock the get all products method. 131 00:06:01,290 --> 00:06:02,763 So in my rest client, 132 00:06:04,260 --> 00:06:05,380 in my rest client 133 00:06:06,240 --> 00:06:09,060 my rest client had a function 134 00:06:09,060 --> 00:06:11,070 called get all products 135 00:06:11,070 --> 00:06:12,810 and that's what I'm going to be testing, 136 00:06:12,810 --> 00:06:13,643 get 137 00:06:14,520 --> 00:06:15,353 all 138 00:06:16,530 --> 00:06:17,363 products. 139 00:06:20,580 --> 00:06:21,569 Okay. 140 00:06:21,569 --> 00:06:22,770 So I'm gonna basically 141 00:06:22,770 --> 00:06:25,140 my test is gonna be calling that function. 142 00:06:25,140 --> 00:06:28,420 And as we know, when we call that function 143 00:06:29,880 --> 00:06:30,713 in our code 144 00:06:32,010 --> 00:06:34,800 that function will call ax get, 145 00:06:34,800 --> 00:06:36,810 I need to mock that function. 146 00:06:36,810 --> 00:06:40,596 Okay, so I mock the Axios get function. 147 00:06:40,596 --> 00:06:44,280 When I think it's calling the Axios get function, 148 00:06:44,280 --> 00:06:47,580 it's calling a mock version of that function. 149 00:06:47,580 --> 00:06:51,150 And remember when you have a function that returns promise, 150 00:06:51,150 --> 00:06:54,720 you can specify a mock return value not of the promise 151 00:06:54,720 --> 00:06:58,410 but of the resolved result of that promise one step further. 152 00:06:58,410 --> 00:07:00,030 So what I've done here, as I said, 153 00:07:00,030 --> 00:07:03,360 imagine that the get function return to promise 154 00:07:03,360 --> 00:07:05,310 and that promise succeeded 155 00:07:05,310 --> 00:07:08,490 and the final result was this response object. 156 00:07:08,490 --> 00:07:10,410 So I've actually mocked that function 157 00:07:10,410 --> 00:07:14,220 so that the promise or the result of the promise 158 00:07:14,220 --> 00:07:17,730 will be an object that looks like this. 159 00:07:17,730 --> 00:07:20,640 Okay, so what have I actually specified here? 160 00:07:20,640 --> 00:07:23,670 I've specified that the mock return value 161 00:07:23,670 --> 00:07:25,000 is going to be an object 162 00:07:26,100 --> 00:07:28,090 that has a data property 163 00:07:30,134 --> 00:07:32,010 which is an array of products, 164 00:07:32,010 --> 00:07:34,770 the skis and the goggles and the you know what, 165 00:07:34,770 --> 00:07:37,230 plus any other properties that might be relevant. 166 00:07:37,230 --> 00:07:39,150 Well, actually that that's all I've specified 167 00:07:39,150 --> 00:07:40,920 in my mock response object. 168 00:07:40,920 --> 00:07:43,080 The only bit I'm interested in is the data. 169 00:07:43,080 --> 00:07:45,630 I don't want to mock the status code or the headers. 170 00:07:45,630 --> 00:07:48,780 I just want to mock the response that I've kind of mocked 171 00:07:48,780 --> 00:07:51,150 coming back from Axios contains that data 172 00:07:51,150 --> 00:07:53,850 as if it had actually come back from rest service 173 00:07:53,850 --> 00:07:55,650 but without actually haven't done that really, 174 00:07:55,650 --> 00:07:56,493 I've mocked it. 175 00:07:57,990 --> 00:08:00,870 Right, so when I call get all products, 176 00:08:00,870 --> 00:08:02,160 okay, let's just think this through, 177 00:08:02,160 --> 00:08:05,463 when I call get all products, it calls Axios get. 178 00:08:06,900 --> 00:08:09,420 I've mocked that function, so that that function 179 00:08:09,420 --> 00:08:11,760 resolves with the promise. 180 00:08:11,760 --> 00:08:13,062 Okay, so, 181 00:08:13,062 --> 00:08:16,383 there we go, in my test, call that function 182 00:08:16,383 --> 00:08:20,700 that will return basically this data here, 183 00:08:20,700 --> 00:08:23,610 that's the data that we've kind of mocked as the resolution 184 00:08:23,610 --> 00:08:27,090 we said that that function resolves with the data 185 00:08:27,090 --> 00:08:28,935 that I specified up here. 186 00:08:28,935 --> 00:08:33,510 Mock verify that that data we've just got back 187 00:08:33,510 --> 00:08:36,240 is the data that's been specified. 188 00:08:36,240 --> 00:08:39,840 Okay, so verify that the data we got back 189 00:08:39,840 --> 00:08:41,640 is equal to the products. 190 00:08:41,640 --> 00:08:44,850 The data that we've got back is equal to the products. 191 00:08:44,850 --> 00:08:46,800 Okay, so verify that this data here 192 00:08:46,800 --> 00:08:48,243 was successfully returned. 193 00:08:49,410 --> 00:08:52,920 And also if you want to be a hundred percent safe, 194 00:08:52,920 --> 00:08:56,490 you can verify that the Axios get function 195 00:08:56,490 --> 00:08:58,110 was actually invoked. 196 00:08:58,110 --> 00:09:00,360 When I call that function, I can verify 197 00:09:00,360 --> 00:09:02,820 that it did actually call the get function. 198 00:09:02,820 --> 00:09:05,970 And I can verify that it called the get function 199 00:09:05,970 --> 00:09:06,840 with this URL. 200 00:09:06,840 --> 00:09:10,664 I'm checking that my function here get all products invoked 201 00:09:10,664 --> 00:09:14,220 used the correct URL to talk to the rest service. 202 00:09:14,220 --> 00:09:18,210 Did it actually use the correct URL when it said get? 203 00:09:18,210 --> 00:09:20,490 That's worth checking because that's could be a bug, 204 00:09:20,490 --> 00:09:21,510 you know, in the code. 205 00:09:21,510 --> 00:09:22,593 Imagine in my code, 206 00:09:23,550 --> 00:09:26,490 I'd actually had the the incorrect URL here. 207 00:09:26,490 --> 00:09:29,700 Imagine I'd misspelled products as being like that, okay, 208 00:09:29,700 --> 00:09:30,533 that would be a bug. 209 00:09:30,533 --> 00:09:33,990 So I can check that when I call get all products 210 00:09:33,990 --> 00:09:37,260 it does actually use the correct URL 211 00:09:37,260 --> 00:09:38,283 in the get call. 212 00:09:39,390 --> 00:09:42,360 When the get call was invoked, verify that it was invoked 213 00:09:42,360 --> 00:09:43,443 with the correct URL. 214 00:09:44,490 --> 00:09:47,070 Oh look, it wasn't, let's fix it. 215 00:09:47,070 --> 00:09:48,220 There we go, now it is. 216 00:09:49,770 --> 00:09:51,660 Okay, that's the first test. 217 00:09:51,660 --> 00:09:54,383 So note in retrospectively, 218 00:09:54,383 --> 00:09:58,680 we specify that the Axios get function should return 219 00:09:58,680 --> 00:10:02,280 a promise which resolves with that response that object 220 00:10:02,280 --> 00:10:04,560 an object that has a data property. 221 00:10:04,560 --> 00:10:05,823 Good. 222 00:10:05,823 --> 00:10:08,802 When we call the rest API, 223 00:10:08,802 --> 00:10:11,520 it should call the mock version of get 224 00:10:11,520 --> 00:10:13,710 which returns this mock result, 225 00:10:13,710 --> 00:10:16,200 verify that it contains the right data 226 00:10:16,200 --> 00:10:19,500 and verify that it actually called the get function 227 00:10:19,500 --> 00:10:22,503 with the correct URL in the first place up there. 228 00:10:24,060 --> 00:10:26,223 Okay, second test 229 00:10:26,223 --> 00:10:31,223 is where I want to test the other function in my rest API, 230 00:10:32,100 --> 00:10:34,410 'cause remember I have another function here 231 00:10:34,410 --> 00:10:36,360 that returns one product. 232 00:10:36,360 --> 00:10:39,960 So I'm gonna go through the same kind of process as before. 233 00:10:39,960 --> 00:10:43,923 So here's my Axios module, 234 00:10:44,790 --> 00:10:46,380 which I've mocked 235 00:10:46,380 --> 00:10:48,840 and there's a get function 236 00:10:48,840 --> 00:10:49,980 which I've mocked. 237 00:10:49,980 --> 00:10:52,623 Here's my rest client, which I'm testing. 238 00:10:54,690 --> 00:10:56,350 So this is my rest 239 00:10:57,750 --> 00:10:58,583 client, 240 00:10:59,572 --> 00:11:01,680 there you go in my best writing. 241 00:11:01,680 --> 00:11:04,230 I'm now invoking on my rest client, 242 00:11:04,230 --> 00:11:07,140 I'm invoking get product by ID. 243 00:11:07,140 --> 00:11:09,450 Okay, so that's the second method really 244 00:11:09,450 --> 00:11:11,100 get 245 00:11:11,100 --> 00:11:11,933 product 246 00:11:13,230 --> 00:11:14,490 by 247 00:11:14,490 --> 00:11:16,062 ID 248 00:11:16,062 --> 00:11:18,000 and a pass in ID one. 249 00:11:18,000 --> 00:11:21,030 So well as we know, and we can check in the code actually 250 00:11:21,030 --> 00:11:23,623 because I'm just kind of showing you the after effect, 251 00:11:23,623 --> 00:11:26,100 when I call get product by ID, 252 00:11:26,100 --> 00:11:28,110 it should call Axios get 253 00:11:28,110 --> 00:11:32,640 with a URL such as example com API product slash one. 254 00:11:32,640 --> 00:11:34,740 So I need to mock that function. 255 00:11:34,740 --> 00:11:37,290 The last thing I want is for that to actually be invoked. 256 00:11:37,290 --> 00:11:39,870 So let's mock that function, shall we? 257 00:11:39,870 --> 00:11:43,080 Let's mock the Axios get function so that it resolves 258 00:11:43,080 --> 00:11:44,640 with just one product. 259 00:11:44,640 --> 00:11:47,130 It returns a response that has just one product. 260 00:11:47,130 --> 00:11:50,010 Okay, so in other words, I'm mocking the get function 261 00:11:50,010 --> 00:11:51,750 it will call the get function 262 00:11:51,750 --> 00:11:54,723 and I'm mocking it so that it will return a promise. 263 00:11:55,680 --> 00:12:00,240 And in that promise, it'll resolve with an object 264 00:12:00,240 --> 00:12:02,230 and that object has a data property 265 00:12:03,750 --> 00:12:06,300 which is one product, okay? 266 00:12:06,300 --> 00:12:09,137 The resolved result is this response, 267 00:12:09,137 --> 00:12:12,420 a data object with a data property, which is one product 268 00:12:12,420 --> 00:12:15,243 as if it's come back from an actual rest service call. 269 00:12:16,710 --> 00:12:18,177 Okay. 270 00:12:18,177 --> 00:12:19,290 So let's verify that happened 271 00:12:19,290 --> 00:12:22,860 when I call get product by ID with one, 272 00:12:22,860 --> 00:12:25,830 what I get back here, is it the data that I get back, 273 00:12:25,830 --> 00:12:28,890 is it the product one as expected? 274 00:12:28,890 --> 00:12:30,210 It should be. 275 00:12:30,210 --> 00:12:32,970 Oh, and also verify that the correct URL 276 00:12:32,970 --> 00:12:34,650 was specified in the call. 277 00:12:34,650 --> 00:12:39,210 When I call get product by ID, it'll call Axios get, 278 00:12:39,210 --> 00:12:42,570 make sure that we called it with the correct parameter 279 00:12:42,570 --> 00:12:46,110 with the correct URL, example com API products one. 280 00:12:46,110 --> 00:12:47,940 Whatever parameters passed in there, 281 00:12:47,940 --> 00:12:51,000 verify that it generated the correct URL 282 00:12:51,000 --> 00:12:52,690 to send into the get request 283 00:12:54,510 --> 00:12:55,950 there. 284 00:12:55,950 --> 00:12:56,850 Okay, so there we go. 285 00:12:56,850 --> 00:12:58,500 So just a note then, 286 00:12:58,500 --> 00:13:01,380 I specify that the get function will resolve 287 00:13:01,380 --> 00:13:03,243 with a result one product. 288 00:13:04,110 --> 00:13:06,390 And then I make the call 289 00:13:06,390 --> 00:13:10,170 and I verify that it gave me back the right result 290 00:13:10,170 --> 00:13:12,600 and that it actually called the get function correctly 291 00:13:12,600 --> 00:13:14,970 in the first place with that correct URL. 292 00:13:14,970 --> 00:13:17,040 So I'm testing two aspects, really. 293 00:13:17,040 --> 00:13:17,910 I'm testing the fact 294 00:13:17,910 --> 00:13:20,160 that it did actually call the get function properly, 295 00:13:20,160 --> 00:13:23,373 and I'm testing that it handled the result properly as well. 296 00:13:24,690 --> 00:13:26,670 Okay, so. 297 00:13:26,670 --> 00:13:27,503 That's it. 298 00:13:27,503 --> 00:13:29,160 All we need to do now is run the tests. 299 00:13:29,160 --> 00:13:32,190 Well, I've run them before and they work. 300 00:13:32,190 --> 00:13:33,023 So there we are. 301 00:13:33,023 --> 00:13:36,840 So what we've seen here then is we had a rest client 302 00:13:36,840 --> 00:13:39,667 and the rest client was using Axios, okay, 303 00:13:39,667 --> 00:13:41,550 and Axios is a low-level library 304 00:13:41,550 --> 00:13:45,390 that actually does rest calls, and I've mocked that level. 305 00:13:45,390 --> 00:13:48,420 So when I call my rest client and it calls into Axios, 306 00:13:48,420 --> 00:13:50,490 I created a mock version of Axios 307 00:13:50,490 --> 00:13:53,550 so that it doesn't actually issue real rest calls, 308 00:13:53,550 --> 00:13:55,920 it has mock results instead 309 00:13:55,920 --> 00:13:58,380 which allows me to test my rest API 310 00:13:58,380 --> 00:14:00,880 as well as the rest of the code in my application.