1 00:00:06,597 --> 00:00:10,080 - In this section, we're going to see how to test Promises. 2 00:00:10,080 --> 00:00:12,300 The previous section introduced Promises 3 00:00:12,300 --> 00:00:14,640 and how they work, resolving and rejecting. 4 00:00:14,640 --> 00:00:16,230 And we saw a function that looks 5 00:00:16,230 --> 00:00:19,980 like this in the TestingPromises folder for lesson four. 6 00:00:19,980 --> 00:00:21,623 We saw a function called doTask 7 00:00:23,128 --> 00:00:24,870 where we passed in a task number 8 00:00:24,870 --> 00:00:26,790 like one, two, three, four, five 9 00:00:26,790 --> 00:00:29,610 and a random number between zero and one 10 00:00:29,610 --> 00:00:32,313 and the function between the Promise. 11 00:00:32,313 --> 00:00:34,860 The Promise had some code in here 12 00:00:34,860 --> 00:00:38,463 which ran a long running task in this function here. 13 00:00:39,390 --> 00:00:43,686 We had a timeout which was kind of a randomized time. 14 00:00:43,686 --> 00:00:45,960 After that timeout occurred, 15 00:00:45,960 --> 00:00:47,580 the random number depended 16 00:00:47,580 --> 00:00:50,760 on whether it was greater than or less than 0.5. 17 00:00:50,760 --> 00:00:52,590 We either called the resolve call 18 00:00:52,590 --> 00:00:55,560 back on the Promise to say yes, it worked, 19 00:00:55,560 --> 00:00:57,090 and here's the result. 20 00:00:57,090 --> 00:01:00,840 Or if the random number was too big, greater than 0.5 21 00:01:00,840 --> 00:01:03,120 we tell the Promise that it rejected 22 00:01:03,120 --> 00:01:04,800 with an error message here. 23 00:01:04,800 --> 00:01:05,633 Okay? 24 00:01:05,633 --> 00:01:09,630 So that's the code in task.js in the demo folder. 25 00:01:09,630 --> 00:01:11,190 Here it is. 26 00:01:11,190 --> 00:01:12,960 If you wanna have a look for yourself, 27 00:01:12,960 --> 00:01:15,990 that's the doTask function I just showed. 28 00:01:15,990 --> 00:01:18,180 And what we're gonna do now is see how to test it. 29 00:01:18,180 --> 00:01:20,580 How can we test that it returns, 30 00:01:20,580 --> 00:01:22,320 that it resolves when it should 31 00:01:22,320 --> 00:01:24,270 and it rejects when it should. 32 00:01:24,270 --> 00:01:25,860 Okay. So this is one way to do it. 33 00:01:25,860 --> 00:01:29,730 First of all, how can you check that a Promise resolves? 34 00:01:29,730 --> 00:01:30,750 This is what you do. 35 00:01:30,750 --> 00:01:32,850 I've got a test function here. 36 00:01:32,850 --> 00:01:35,310 It tests that the task resolves 37 00:01:35,310 --> 00:01:38,073 if the random number was less than 0.5. 38 00:01:39,300 --> 00:01:41,640 Okay, so note these points. 39 00:01:41,640 --> 00:01:44,820 Well first of all, what you do is you call the function 40 00:01:44,820 --> 00:01:46,062 that you're trying to test. 41 00:01:46,062 --> 00:01:47,070 Okay? 42 00:01:47,070 --> 00:01:48,330 So that, I call the function 43 00:01:48,330 --> 00:01:51,222 with a small number, less than 0.5. 44 00:01:51,222 --> 00:01:54,432 Ideally, if that function is working correctly 45 00:01:54,432 --> 00:01:56,280 it should resolve. 46 00:01:56,280 --> 00:02:00,090 It returns a Promise and that Promise should resolve. 47 00:02:00,090 --> 00:02:02,850 Okay, so I take that Promise object that it returns, 48 00:02:02,850 --> 00:02:05,673 and upon that Promise object, I call then. 49 00:02:06,870 --> 00:02:08,490 So this should happen. 50 00:02:08,490 --> 00:02:10,650 The Promise, if it's working correctly 51 00:02:10,650 --> 00:02:13,667 this function should return a Promise that resolves 52 00:02:13,667 --> 00:02:16,683 and it should pass me the result. 53 00:02:17,550 --> 00:02:20,340 And I passed in a value one here, 54 00:02:20,340 --> 00:02:23,010 so it should, the result should be, 55 00:02:23,010 --> 00:02:25,200 and this is where you put your expect. 56 00:02:25,200 --> 00:02:28,350 The result should be Task 1 resolved. 57 00:02:28,350 --> 00:02:29,610 That was the task number. 58 00:02:29,610 --> 00:02:32,475 This is the string I'm expecting to get back. 59 00:02:32,475 --> 00:02:33,540 Okay? 60 00:02:33,540 --> 00:02:37,650 So you call the function, which returns a Promise. 61 00:02:37,650 --> 00:02:39,540 You assert the result of that Promise. 62 00:02:39,540 --> 00:02:42,663 And then you return that Promise object back to Jest. 63 00:02:43,530 --> 00:02:46,860 Jest waits for that Promise object to finish 64 00:02:46,860 --> 00:02:49,110 before it moves on beyond the test. 65 00:02:49,110 --> 00:02:52,950 Okay, so you have to return this Promise object here. 66 00:02:52,950 --> 00:02:55,170 You have to return back to Jest 67 00:02:55,170 --> 00:02:58,500 so that Jest knows to wait for that Promise object 68 00:02:58,500 --> 00:03:01,230 to finish before it can go on to the next test 69 00:03:01,230 --> 00:03:04,532 so it doesn't kind of terminate prematurely. 70 00:03:04,532 --> 00:03:09,532 So that's how to test if my Promise object was resolved. 71 00:03:10,530 --> 00:03:11,940 Similar kind of idea to test 72 00:03:11,940 --> 00:03:13,220 if it rejects. 73 00:03:13,220 --> 00:03:16,320 In this case here I'm testing that my task, 74 00:03:16,320 --> 00:03:18,060 the function that I'm calling, 75 00:03:18,060 --> 00:03:20,490 tells the Promise that it rejects 76 00:03:20,490 --> 00:03:23,043 if the value is 0.5 or higher. 77 00:03:24,480 --> 00:03:27,090 Okay, now then there is a slight complication here 78 00:03:27,090 --> 00:03:28,860 which I'll get back to in a moment. 79 00:03:28,860 --> 00:03:30,510 The first thing you have to do 80 00:03:30,510 --> 00:03:35,510 is you have to specify how many assertions do you expect 81 00:03:35,580 --> 00:03:37,890 to happen in this test? 82 00:03:37,890 --> 00:03:38,790 What this statement does, 83 00:03:38,790 --> 00:03:39,960 we haven't seen it before, 84 00:03:39,960 --> 00:03:43,260 I'm telling Jest I expect one assertion, 85 00:03:43,260 --> 00:03:47,234 one expect call, in other words, to happen in my test. 86 00:03:47,234 --> 00:03:48,067 Okay? 87 00:03:48,067 --> 00:03:53,067 So one expect test must happen when this test... 88 00:03:53,490 --> 00:03:55,920 Not this expect, but this expect. 89 00:03:55,920 --> 00:03:58,950 I'm making sure that at least one assertion happens 90 00:03:58,950 --> 00:04:00,603 when this test is executed. 91 00:04:01,530 --> 00:04:04,110 Bear that thought in mind for a moment. 92 00:04:04,110 --> 00:04:06,240 Okay, what I then do is similar to before. 93 00:04:06,240 --> 00:04:09,900 I call my function into test, giving it some sample values, 94 00:04:09,900 --> 00:04:13,830 Task 1, a value that should cause rejection. 95 00:04:13,830 --> 00:04:14,663 Okay? 96 00:04:14,663 --> 00:04:16,980 So, you know, if my function is written correctly, 97 00:04:16,980 --> 00:04:21,553 it should resolve, it should reject the Promise. 98 00:04:23,160 --> 00:04:28,020 And I catch that problem in my catch function here. 99 00:04:28,020 --> 00:04:28,853 Okay? 100 00:04:28,853 --> 00:04:31,350 And then don't forget to return the result 101 00:04:31,350 --> 00:04:33,900 of this promise back to Jest. 102 00:04:33,900 --> 00:04:37,290 Now the reason why you need expect.assertions here 103 00:04:37,290 --> 00:04:39,543 is to guard against a false positive. 104 00:04:40,740 --> 00:04:44,580 Imagine that there was a bug in my code, 105 00:04:44,580 --> 00:04:48,720 and I was hoping that my code would reject 106 00:04:48,720 --> 00:04:53,445 but because of a bug, this code actually resolves. 107 00:04:53,445 --> 00:04:54,278 Okay? 108 00:04:54,278 --> 00:04:57,090 So if that task inadvertently resolved 109 00:04:57,090 --> 00:05:00,003 then this code would never be executed. 110 00:05:00,992 --> 00:05:05,130 And therefore it wouldn't actually get to my expect clause. 111 00:05:05,130 --> 00:05:06,750 So I'd get a false positive there. 112 00:05:06,750 --> 00:05:08,460 I wouldn't get any problems here. 113 00:05:08,460 --> 00:05:10,620 It would never get into my catch handler 114 00:05:10,620 --> 00:05:14,097 because the task didn't reject. 115 00:05:14,097 --> 00:05:17,520 So this expect.assertions is a guard 116 00:05:17,520 --> 00:05:19,410 against a false positive. 117 00:05:19,410 --> 00:05:22,110 If there was a bug in my function here 118 00:05:22,110 --> 00:05:24,776 and it resolved when it should reject, 119 00:05:24,776 --> 00:05:27,990 this function would return immediately, 120 00:05:27,990 --> 00:05:29,790 but Jest would give me an error 121 00:05:29,790 --> 00:05:32,700 because it didn't run through this expect clause 122 00:05:32,700 --> 00:05:34,500 because it resolved, not rejected. 123 00:05:34,500 --> 00:05:35,970 It didn't get into here. 124 00:05:35,970 --> 00:05:37,830 It never ran that code. 125 00:05:37,830 --> 00:05:40,530 Therefore, we didn't get one assertion 126 00:05:40,530 --> 00:05:43,080 and it would fail because of that reason. 127 00:05:43,080 --> 00:05:43,913 Okay? 128 00:05:43,913 --> 00:05:45,480 So that's the guard against, 129 00:05:45,480 --> 00:05:49,230 or to check that the Promise didn't accidentally resolve 130 00:05:49,230 --> 00:05:50,760 when it should have rejected. 131 00:05:50,760 --> 00:05:52,470 You do need that there to make sure 132 00:05:52,470 --> 00:05:54,670 that this statement was actually executed. 133 00:05:54,670 --> 00:05:57,870 And don't forget to return the Promise object 134 00:05:57,870 --> 00:06:00,123 back at the end of your test as well. 135 00:06:01,020 --> 00:06:04,560 So to run that test, to run those two tests, 136 00:06:04,560 --> 00:06:05,947 you could do it like this. 137 00:06:05,947 --> 00:06:08,673 - t test promises using then/catch. 138 00:06:10,030 --> 00:06:10,863 Okay? 139 00:06:10,863 --> 00:06:12,300 That will take for both of those tests 140 00:06:12,300 --> 00:06:13,800 that I just showed you. 141 00:06:13,800 --> 00:06:17,538 If you run that test command from the test folder 142 00:06:17,538 --> 00:06:21,510 then it'll run this function here. 143 00:06:21,510 --> 00:06:25,320 Task resolves if value < 0.5. 144 00:06:25,320 --> 00:06:28,710 And task rejects if value > 0.5. 145 00:06:28,710 --> 00:06:30,960 This string here, 146 00:06:30,960 --> 00:06:33,003 test promises using then/catch, 147 00:06:34,260 --> 00:06:35,460 and my task suite 148 00:06:35,460 --> 00:06:40,460 that's the suite here that contains those two tests, 149 00:06:40,560 --> 00:06:44,790 testing that it rejected, so resolved and rejected 150 00:06:44,790 --> 00:06:45,990 when it should have done. 151 00:06:45,990 --> 00:06:47,733 That's that first suite there. 152 00:06:49,170 --> 00:06:50,040 Now as it happens, 153 00:06:50,040 --> 00:06:52,467 there is another way to test Promises. 154 00:06:52,467 --> 00:06:57,180 There is a resolves matcher and rejects matcher. 155 00:06:57,180 --> 00:06:58,770 So this is, you might prefer this 156 00:06:58,770 --> 00:07:01,050 as an alternative, easier way 157 00:07:01,050 --> 00:07:04,380 to check if a Promise has succeeded or failed. 158 00:07:04,380 --> 00:07:09,380 So here, what you do is you call the expect function 159 00:07:11,010 --> 00:07:12,810 and you give it the function 160 00:07:12,810 --> 00:07:13,950 that you are operating on. 161 00:07:13,950 --> 00:07:17,790 So this function here should return a Promise. 162 00:07:17,790 --> 00:07:18,623 Okay? 163 00:07:18,623 --> 00:07:23,112 So you say I'm expecting that this Promise resolves 164 00:07:23,112 --> 00:07:26,943 and I'm expecting the result to be Task 1 resolved. 165 00:07:28,086 --> 00:07:33,086 Likewise, and then you return this construct. 166 00:07:33,450 --> 00:07:34,283 Okay? 167 00:07:34,283 --> 00:07:35,130 Because basically it's gonna return a Promise 168 00:07:35,130 --> 00:07:36,720 back to Jest. 169 00:07:36,720 --> 00:07:40,050 Alternatively, you can say right call that function, 170 00:07:40,050 --> 00:07:41,730 that returns a Promise. 171 00:07:41,730 --> 00:07:44,580 I'm expecting that return value, that Promise, 172 00:07:44,580 --> 00:07:48,480 to reject and I'm expecting the error message to be 173 00:07:48,480 --> 00:07:50,010 Task 1 rejected. 174 00:07:50,010 --> 00:07:51,870 So the resolves matcher 175 00:07:51,870 --> 00:07:54,630 and the rejects matcher is a cleaner alternative 176 00:07:54,630 --> 00:07:56,100 to what we just showed you 177 00:07:56,100 --> 00:07:57,480 as a way of dealing with Promises 178 00:07:57,480 --> 00:08:00,033 that may succeed or may fail. 179 00:08:01,740 --> 00:08:05,280 So if you run that bunch of tests, 180 00:08:05,280 --> 00:08:08,550 those tests are in this suite here, 181 00:08:08,550 --> 00:08:12,183 test promises using resolves/rejects matchers. 182 00:08:13,440 --> 00:08:16,370 So it uses the resolves matcher 183 00:08:16,370 --> 00:08:18,150 and the rejects matcher. 184 00:08:18,150 --> 00:08:21,180 Call the function returns a Promise. 185 00:08:21,180 --> 00:08:24,390 Expect that returned Promise to resolve 186 00:08:24,390 --> 00:08:25,920 with that value. 187 00:08:25,920 --> 00:08:28,410 Call the function returns a Promise. 188 00:08:28,410 --> 00:08:32,160 Expect that Promise to reject with that error message. 189 00:08:32,160 --> 00:08:32,993 Okay? 190 00:08:32,993 --> 00:08:36,450 So when I run this test suite, my code is correct 191 00:08:36,450 --> 00:08:39,783 so my test suite should succeed and there you go.