1 00:00:06,540 --> 00:00:08,760 - In this section, we're going to dig a bit deeper 2 00:00:08,760 --> 00:00:11,700 into reactive extensions for JavaScript. 3 00:00:11,700 --> 00:00:13,320 In particular, we're going to see 4 00:00:13,320 --> 00:00:15,000 how to create an observable 5 00:00:15,000 --> 00:00:17,070 which emits not just one value 6 00:00:17,070 --> 00:00:19,590 but a stream of multiple values. 7 00:00:19,590 --> 00:00:22,470 And then we'll see how we can test the observable 8 00:00:22,470 --> 00:00:23,850 in our test code. 9 00:00:23,850 --> 00:00:27,150 We can receive multiple values which were emitted 10 00:00:27,150 --> 00:00:30,810 and we'll also see how to test for errors as well. 11 00:00:30,810 --> 00:00:34,590 An observable can emit errors as well as proper results. 12 00:00:34,590 --> 00:00:36,546 So we'd need to test for that. 13 00:00:36,546 --> 00:00:40,050 Okay. If you are interested in following along, 14 00:00:40,050 --> 00:00:42,750 this is the folder where the demos are located 15 00:00:42,750 --> 00:00:46,173 for this section testing RxJS techniques. 16 00:00:47,010 --> 00:00:49,740 Okay. So we're gonna look at three different functions. 17 00:00:49,740 --> 00:00:53,160 Each will return an observable 18 00:00:53,160 --> 00:00:55,890 and we'll see how to test the observable in each case. 19 00:00:55,890 --> 00:00:59,850 So the first function emit stream one. 20 00:00:59,850 --> 00:01:02,430 So what I do is there's a form function 21 00:01:02,430 --> 00:01:04,710 in the reactive extensions library, 22 00:01:04,710 --> 00:01:07,860 the form function you give it an array 23 00:01:07,860 --> 00:01:11,580 and it'll create an observable, which emits those values. 24 00:01:11,580 --> 00:01:16,500 Okay? So this observable will emit the value a hundred 25 00:01:16,500 --> 00:01:18,660 then 200, 300, 400, 500. 26 00:01:18,660 --> 00:01:22,620 When it's finished, it'll emit a complete signal to say 27 00:01:22,620 --> 00:01:24,060 no more data. 28 00:01:24,060 --> 00:01:26,070 So if you wanted to test that, 29 00:01:26,070 --> 00:01:29,130 if you wanted to test that the observable returns 30 00:01:29,130 --> 00:01:31,320 the correct data, have a look at this. 31 00:01:31,320 --> 00:01:34,230 This is my test for the emit stream one function, 32 00:01:34,230 --> 00:01:35,880 a test in that function there. 33 00:01:35,880 --> 00:01:37,410 So I call the function. 34 00:01:37,410 --> 00:01:39,480 It returns an observable. 35 00:01:39,480 --> 00:01:42,270 That observable is gonna pump out five values, 36 00:01:42,270 --> 00:01:44,010 separated by a hundred. 37 00:01:44,010 --> 00:01:45,840 Okay? So we would expect 38 00:01:45,840 --> 00:01:48,390 the first value to be emitted to be a hundred. 39 00:01:48,390 --> 00:01:50,910 We would expect the second value to be 40 00:01:50,910 --> 00:01:53,790 200 and then 300 and so on. 41 00:01:53,790 --> 00:01:56,160 So I've kind of got a little trick here. 42 00:01:56,160 --> 00:01:58,740 What I've done is I've set up a, a help available 43 00:01:58,740 --> 00:02:02,880 which is the value that I expect to receive next. 44 00:02:02,880 --> 00:02:04,860 So I subscribe to my observable. 45 00:02:04,860 --> 00:02:08,310 When I call that function, it returns an observable object. 46 00:02:08,310 --> 00:02:12,300 I subscribe to it and I wait for the next value to arrive. 47 00:02:12,300 --> 00:02:16,980 Now, the first value that comes in it should be a hundred. 48 00:02:16,980 --> 00:02:19,950 So I check that value to be a hundred, 49 00:02:19,950 --> 00:02:23,970 expected is the current value of my local variable. 50 00:02:23,970 --> 00:02:26,340 Okay? So is the value emitted a hundred? 51 00:02:26,340 --> 00:02:27,480 It should be. 52 00:02:27,480 --> 00:02:29,820 And then being a bit crafty, 53 00:02:29,820 --> 00:02:32,520 I then increment my local variable here 54 00:02:32,520 --> 00:02:36,300 to be 200, ready to test the next value. 55 00:02:36,300 --> 00:02:38,130 So when the next value is emitted, 56 00:02:38,130 --> 00:02:40,000 we test that that value is 200 57 00:02:41,070 --> 00:02:44,163 and then we increment our expected value to be 300. 58 00:02:45,270 --> 00:02:49,680 Okay? So the next value that comes in is that value, 300. 59 00:02:49,680 --> 00:02:53,010 So this value here in this hard coded example, 60 00:02:53,010 --> 00:02:54,660 where I know that the values are separated 61 00:02:54,660 --> 00:02:56,730 by a hundred each time, 62 00:02:56,730 --> 00:02:59,340 I can kind of keep track of that in my code here 63 00:02:59,340 --> 00:03:01,350 to check that the value that I've got 64 00:03:01,350 --> 00:03:03,330 is the correct value and then a hundred more 65 00:03:03,330 --> 00:03:05,250 for the next value and then a hundred more 66 00:03:05,250 --> 00:03:06,237 for the next value. 67 00:03:06,237 --> 00:03:08,040 And so on. 68 00:03:08,040 --> 00:03:10,950 When it's finished emitting the value 500, 69 00:03:10,950 --> 00:03:13,980 my observable will then emit the complete signal 70 00:03:13,980 --> 00:03:16,140 which I have to handle here 71 00:03:16,140 --> 00:03:18,630 because you have to, at some point, tell JS 72 00:03:18,630 --> 00:03:20,640 there aren't any more values to come. 73 00:03:20,640 --> 00:03:23,730 So when the complete signal comes from the observable, 74 00:03:23,730 --> 00:03:26,310 remember when you subscribe to an observable, 75 00:03:26,310 --> 00:03:28,080 it'll give you the next value each time 76 00:03:28,080 --> 00:03:30,120 but it'll also tell you when it's finished. 77 00:03:30,120 --> 00:03:33,510 So when it's finished, we have to tell JS we're done 78 00:03:33,510 --> 00:03:36,180 and call in the JS callback function to say, 79 00:03:36,180 --> 00:03:39,090 we can move on now, that's the end of that test. 80 00:03:39,090 --> 00:03:42,303 There will be no more values emitted from that observable. 81 00:03:44,070 --> 00:03:46,770 Okay. Now the next slide, a bit more realistic 82 00:03:46,770 --> 00:03:48,750 where we don't necessarily know exactly 83 00:03:48,750 --> 00:03:50,790 what the values are going to be. 84 00:03:50,790 --> 00:03:52,263 So if we have a look at this, 85 00:03:53,610 --> 00:03:56,250 we have a function called emit stream two. 86 00:03:56,250 --> 00:03:58,500 It's going to create an observable 87 00:03:58,500 --> 00:04:02,070 which emits a specified number of values. 88 00:04:02,070 --> 00:04:05,970 So let's say I pass the value five into this function. 89 00:04:05,970 --> 00:04:10,320 It'll create an observable based on this array, 90 00:04:10,320 --> 00:04:14,610 this array in JavaScript, there's an array dot form function 91 00:04:14,610 --> 00:04:17,820 equips an array of the specified length 92 00:04:17,820 --> 00:04:21,060 and it generates each value via a lambda. 93 00:04:21,060 --> 00:04:23,070 So if you have a length of five, 94 00:04:23,070 --> 00:04:26,040 it'll create an array of five elements and it'll call 95 00:04:26,040 --> 00:04:28,920 this function to generate each of those values. 96 00:04:28,920 --> 00:04:30,630 Basically this generates a number 97 00:04:30,630 --> 00:04:32,160 between zero and a hundred. 98 00:04:32,160 --> 00:04:34,140 That's the basic idea. 99 00:04:34,140 --> 00:04:36,630 So that's what's gonna be generated. 100 00:04:36,630 --> 00:04:41,160 When I call this function it'll create an observable object 101 00:04:41,160 --> 00:04:43,680 and that observable object will omit the values 102 00:04:43,680 --> 00:04:44,760 in this array. 103 00:04:44,760 --> 00:04:47,490 Each value, there will be five of them, let's say. 104 00:04:47,490 --> 00:04:50,703 Each value will be or should be between zero and a hundred. 105 00:04:51,900 --> 00:04:54,393 So let's see how we can test that function. 106 00:04:55,440 --> 00:04:58,140 So to test emit stream two, call that function 107 00:04:58,140 --> 00:04:59,580 with the value five. 108 00:04:59,580 --> 00:05:01,800 So pass the value five in here, 109 00:05:01,800 --> 00:05:03,990 it creates an array of five elements, 110 00:05:03,990 --> 00:05:08,880 generates five random numbers between zero and a hundred 111 00:05:08,880 --> 00:05:12,240 and emits those values in an observable. 112 00:05:12,240 --> 00:05:14,880 So it returns an observable object. 113 00:05:14,880 --> 00:05:18,270 Grab that observable object and subscribe to it. 114 00:05:18,270 --> 00:05:20,430 Wait for the next value to arrive. 115 00:05:20,430 --> 00:05:24,840 That should be a value between zero and a hundred. 116 00:05:24,840 --> 00:05:27,210 Okay? So the value that's emitted here, 117 00:05:27,210 --> 00:05:28,650 according to this business rule, 118 00:05:28,650 --> 00:05:30,810 it should be a number between zero and a hundred. 119 00:05:30,810 --> 00:05:35,380 Check that the value emitted is in the specified range 120 00:05:36,480 --> 00:05:38,340 and then wait for the next value 121 00:05:38,340 --> 00:05:39,173 and the next value. 122 00:05:39,173 --> 00:05:40,320 That will go around five times, 123 00:05:40,320 --> 00:05:42,270 that'll be called five times. 124 00:05:42,270 --> 00:05:46,170 And eventually, you know, when the observable has finished 125 00:05:46,170 --> 00:05:49,110 emitting all the values from the array, 126 00:05:49,110 --> 00:05:51,030 it'll emit the complete signal, 127 00:05:51,030 --> 00:05:54,453 handle that and tell JS that's the end of this test. 128 00:05:56,010 --> 00:05:57,663 One last thing to think about. 129 00:05:58,530 --> 00:06:00,990 Observables can also emit errors, 130 00:06:00,990 --> 00:06:02,250 so let's check for that. 131 00:06:02,250 --> 00:06:03,420 Have a look at this. 132 00:06:03,420 --> 00:06:05,400 This is my third function. 133 00:06:05,400 --> 00:06:08,910 So it takes a parameter, but it does some error check in. 134 00:06:08,910 --> 00:06:10,980 If the parameter here is like, 135 00:06:10,980 --> 00:06:13,290 it's meant to be a length of an array, 136 00:06:13,290 --> 00:06:16,890 but if it's zero or negative, that's no good. 137 00:06:16,890 --> 00:06:21,120 So in that case, this is how you can create an observable 138 00:06:21,120 --> 00:06:23,610 which emits an error. 139 00:06:23,610 --> 00:06:25,890 You say, rxjs throw error. 140 00:06:25,890 --> 00:06:30,330 It creates an observable and observable raises this error. 141 00:06:30,330 --> 00:06:33,180 Okay? It basically triggers an error callback 142 00:06:33,180 --> 00:06:34,080 with that message. 143 00:06:34,950 --> 00:06:38,100 So let's see when I call this function 144 00:06:38,100 --> 00:06:40,260 with a negative value or zero value, 145 00:06:40,260 --> 00:06:43,080 I can test but it does indeed throw an error. 146 00:06:43,080 --> 00:06:44,130 Let's see how to do that. 147 00:06:44,130 --> 00:06:47,730 Testing that end observable did raise an error. 148 00:06:47,730 --> 00:06:51,150 So call the function with an invalid parameter. 149 00:06:51,150 --> 00:06:53,250 That should all be in well 150 00:06:53,250 --> 00:06:56,100 create an observable, which emits an error. 151 00:06:56,100 --> 00:06:58,620 Let's subscribe to the observable 152 00:06:58,620 --> 00:07:01,710 and let's see that it did actually throw an error. 153 00:07:01,710 --> 00:07:03,300 Yes, it did. 154 00:07:03,300 --> 00:07:04,743 What was the error message? 155 00:07:05,790 --> 00:07:08,040 When an error is emitted, 156 00:07:08,040 --> 00:07:10,110 the error has a message property. 157 00:07:10,110 --> 00:07:14,370 Verify that the message 'bad length' is correct. 158 00:07:14,370 --> 00:07:17,163 And then we can say to JS, we're done. 159 00:07:18,210 --> 00:07:20,580 Now, if you wanna run any of these tests, 160 00:07:20,580 --> 00:07:23,490 obviously you need to have the reactive extensions library 161 00:07:23,490 --> 00:07:27,180 installed before you can actually run the tests. 162 00:07:27,180 --> 00:07:30,330 So let's just take a quick look at the code. 163 00:07:30,330 --> 00:07:31,920 I've opened up the code folder 164 00:07:31,920 --> 00:07:35,370 for testing reactive extension techniques. 165 00:07:35,370 --> 00:07:39,270 And what I wanted to pick out is the package.json. 166 00:07:39,270 --> 00:07:41,730 Remember that you have to include 167 00:07:41,730 --> 00:07:45,240 the reactive extensions library in your dependency. 168 00:07:45,240 --> 00:07:47,947 Otherwise it'll just, you know, it won't work at all. 169 00:07:48,920 --> 00:07:51,270 So you need to make sure that your package json 170 00:07:51,270 --> 00:07:54,210 includes reactive extensions for JavaScript 171 00:07:54,210 --> 00:07:58,203 and then you also need to do an NPM install. 172 00:08:00,960 --> 00:08:04,290 Okay? So that'll install the reactive extensions library 173 00:08:04,290 --> 00:08:06,000 in your local folder. 174 00:08:06,000 --> 00:08:09,480 Once you've done that, once you've installed the local 175 00:08:09,480 --> 00:08:11,370 once you've installed reactive extensions 176 00:08:11,370 --> 00:08:14,283 in the local folder, then you can run the test. 177 00:08:15,690 --> 00:08:17,910 So I had three functions that were being tested, 178 00:08:17,910 --> 00:08:20,470 a function that emitted in array, a hundred, 179 00:08:20,470 --> 00:08:22,770 200, 300, 400, 500. 180 00:08:22,770 --> 00:08:25,650 The second function that emitted numbers 181 00:08:25,650 --> 00:08:27,720 between zero and 100 five times. 182 00:08:27,720 --> 00:08:30,690 And the third test, which emitted errors. 183 00:08:30,690 --> 00:08:32,100 Okay? So they've all worked nicely. 184 00:08:32,100 --> 00:08:33,660 So there we go. 185 00:08:33,660 --> 00:08:38,660 It's quite important to know how to test reactive extensions 186 00:08:38,970 --> 00:08:41,520 when you are writing in realistic JavaScript, you will, 187 00:08:41,520 --> 00:08:43,320 you know, it's not something that you do all the time, 188 00:08:43,320 --> 00:08:46,770 but you will need occasionally to have an observable 189 00:08:46,770 --> 00:08:49,200 typically from a web socket or a server. 190 00:08:49,200 --> 00:08:52,140 And you have to verify that your observable is 191 00:08:52,140 --> 00:08:56,160 emitting the correct values and errors when expected. 192 00:08:56,160 --> 00:08:57,510 And we've seen her do that.