1 00:00:01,666 --> 00:00:03,060 Teacher: So the react side of our application 2 00:00:03,060 --> 00:00:04,890 is in a pretty good spot. 3 00:00:04,890 --> 00:00:08,039 We have three components: app, comment box, 4 00:00:08,039 --> 00:00:11,880 and comment list, and each of those is pretty well tested 5 00:00:11,880 --> 00:00:12,880 through and through. 6 00:00:14,685 --> 00:00:15,965 The next thing that we need to do 7 00:00:15,965 --> 00:00:18,429 is we need to work on the redux side of things. 8 00:00:18,429 --> 00:00:20,460 So we don't have any specs around the redux side of things 9 00:00:20,460 --> 00:00:22,590 right now and without redux, 10 00:00:22,590 --> 00:00:24,536 we don't really have the ability 11 00:00:24,536 --> 00:00:27,330 to save any of our comments or to communicate those comments 12 00:00:27,330 --> 00:00:30,390 that are saved over to the comment list component. 13 00:00:30,390 --> 00:00:32,850 So we need to first make an action creator 14 00:00:32,850 --> 00:00:35,880 to save each comment as it gets created, 15 00:00:35,880 --> 00:00:38,010 and we also need to make a reducer 16 00:00:38,010 --> 00:00:40,953 to collect all of those comments as they're created. 17 00:00:42,493 --> 00:00:44,550 The comments reducer will be responsible for creating 18 00:00:44,550 --> 00:00:48,060 the comments piece of application state as well. 19 00:00:48,060 --> 00:00:51,063 So let's get started by first making our action creator. 20 00:00:53,347 --> 00:00:56,888 We'll first make a new directory inside of our test folder 21 00:00:56,888 --> 00:00:58,538 for holding our action spec file. 22 00:01:00,210 --> 00:01:03,150 So we'll make a new folder called actions, 23 00:01:03,150 --> 00:01:05,250 and right now inside of our actions folder 24 00:01:07,213 --> 00:01:09,090 inside of our source directory, 25 00:01:09,090 --> 00:01:12,550 we've got an existing actions file called just index 26 00:01:12,550 --> 00:01:13,810 and we're gonna end up putting 27 00:01:13,810 --> 00:01:16,150 all of our action creators in here. 28 00:01:16,150 --> 00:01:19,500 So just to mirror that folder structure one for one, 29 00:01:19,500 --> 00:01:23,670 we're going to create a test file 30 00:01:23,670 --> 00:01:26,340 inside of our test actions directory 31 00:01:26,340 --> 00:01:29,280 and we'll call it index_test. 32 00:01:29,280 --> 00:01:32,790 Now, index_test for a filename is pretty goofy, 33 00:01:32,790 --> 00:01:35,949 if you want to call this actions_test 34 00:01:35,949 --> 00:01:37,288 or something like that instead, 35 00:01:37,288 --> 00:01:39,060 I am whole heartedly behind that, 36 00:01:39,060 --> 00:01:41,580 going with index_test is a little bit strange. 37 00:01:41,580 --> 00:01:44,250 Nonetheless, we're doing it because it is a one to one 38 00:01:44,250 --> 00:01:46,503 mapping with our implementation directory. 39 00:01:48,728 --> 00:01:51,270 So we'll import that file versus you will create that file, 40 00:01:51,270 --> 00:01:54,300 and then inside of here we're ready to write a spec 41 00:01:54,300 --> 00:01:55,893 around our action creator. 42 00:01:57,364 --> 00:02:00,570 So we're going to do this 100% with test driven development 43 00:02:00,570 --> 00:02:02,223 or behavior driven development. 44 00:02:03,069 --> 00:02:04,200 So we're not gonna write a single piece of code 45 00:02:04,200 --> 00:02:07,920 inside of our implementation file, index.js, 46 00:02:07,920 --> 00:02:09,780 we're going to write specs first 47 00:02:09,780 --> 00:02:12,330 and then we'll do the implementation 48 00:02:12,330 --> 00:02:13,950 after we've written all of our specs. 49 00:02:13,950 --> 00:02:18,690 In practice here, the testing action creators 50 00:02:18,690 --> 00:02:20,250 tends to be pretty straightforward 51 00:02:20,250 --> 00:02:22,920 so this shouldn't be too too bad. 52 00:02:22,920 --> 00:02:25,410 So at the top, as with all of our specs, 53 00:02:25,410 --> 00:02:28,667 we need to import some helpers from our test helper file 54 00:02:28,667 --> 00:02:30,723 called test_helper.js. 55 00:02:31,890 --> 00:02:36,350 So we'll import expect from test_helper 56 00:02:38,160 --> 00:02:39,750 and in the other specs we wrote, 57 00:02:39,750 --> 00:02:43,470 we also imported the render component helper as well. 58 00:02:43,470 --> 00:02:45,870 In this case, we're not rendering any components, 59 00:02:45,870 --> 00:02:48,870 we're just testing a action creator 60 00:02:48,870 --> 00:02:51,873 so we don't need that render component helper here. 61 00:02:54,157 --> 00:02:58,293 We're going to describe the actions, all of our actions, 62 00:03:00,616 --> 00:03:03,540 and the action that we're going to test in particular 63 00:03:03,540 --> 00:03:08,370 is a savecomment action creator. 64 00:03:08,370 --> 00:03:10,080 So when we're testing our action creators, 65 00:03:10,080 --> 00:03:12,380 because a lot of the time they'll all just fit 66 00:03:13,240 --> 00:03:15,186 inside of one file, I like to make 67 00:03:15,186 --> 00:03:17,404 a top level describe that says hey, 68 00:03:17,404 --> 00:03:19,350 here's all the actions we're about to test, 69 00:03:19,350 --> 00:03:22,380 and then I make one describe for each action creator, 70 00:03:22,380 --> 00:03:26,460 and inside of here, we can put our various it blocks. 71 00:03:26,460 --> 00:03:28,680 So the first thing I want to make an assertion about, 72 00:03:28,680 --> 00:03:30,600 and this is where we're kind of deviating 73 00:03:30,600 --> 00:03:35,310 from the same culture that we had 74 00:03:35,310 --> 00:03:37,964 around the react side of things 75 00:03:37,964 --> 00:03:40,230 where we were just making assertions about the HTML 76 00:03:40,230 --> 00:03:43,650 or the end product, when we're testing action creators, 77 00:03:43,650 --> 00:03:46,800 we tend to be a little bit more precise 78 00:03:46,800 --> 00:03:48,960 and test it a little lower level. 79 00:03:48,960 --> 00:03:52,530 So we're going to expect that it has the correct type 80 00:03:52,530 --> 00:03:54,603 and it has the correct payload as well. 81 00:03:55,459 --> 00:03:58,073 So we're being very particular here in implementation. 82 00:04:00,007 --> 00:04:03,427 So for our first it block, we'll say it has the correct type 83 00:04:06,540 --> 00:04:11,463 and then we'll also say it has the correct payload. 84 00:04:13,484 --> 00:04:15,330 So I've been saying we're testing our action creators, 85 00:04:15,330 --> 00:04:17,160 but really we're testing the action 86 00:04:17,160 --> 00:04:19,160 that's returned from the action creator. 87 00:04:20,166 --> 00:04:23,280 So we're going to assert both the type and the payload 88 00:04:23,280 --> 00:04:25,710 on the action that gets returned. 89 00:04:25,710 --> 00:04:27,703 So this looks like a pretty good 90 00:04:27,703 --> 00:04:29,700 testing structure right here, what we haven't done yet 91 00:04:29,700 --> 00:04:33,863 is we haven't imported the action creator at the top, 92 00:04:33,863 --> 00:04:36,343 so we should probably at least start to scaffold out 93 00:04:36,343 --> 00:04:38,423 our action creator before we go any further. 94 00:04:39,570 --> 00:04:41,370 Before we make any action creators, 95 00:04:41,370 --> 00:04:44,280 we have to make a type for our action. 96 00:04:44,280 --> 00:04:46,410 So inside of the actions folder, 97 00:04:46,410 --> 00:04:50,160 we'll make a new file, types.js, 98 00:04:50,160 --> 00:04:51,480 and we'll end up just sticking 99 00:04:51,480 --> 00:04:54,750 all of our action types inside of here. 100 00:04:54,750 --> 00:04:57,480 For application, we're only gonna have one type 101 00:04:57,480 --> 00:05:00,930 and it's gonna be just the save_comment type. 102 00:05:00,930 --> 00:05:04,623 So we'll export const save_comment, save_comment. 103 00:05:12,343 --> 00:05:13,620 So now we can make use of this type 104 00:05:13,620 --> 00:05:18,570 inside of our action creator over in source, 105 00:05:18,570 --> 00:05:21,063 actions, index.js. 106 00:05:24,263 --> 00:05:28,250 So over here we can import save_comment from types, 107 00:05:32,002 --> 00:05:35,404 and then we can export our function savecomment, 108 00:05:35,404 --> 00:05:37,604 this is gonna be our action creator like so. 109 00:05:39,223 --> 00:05:41,724 So now we've scaffolded this stuff out, 110 00:05:41,724 --> 00:05:44,801 we can really finish writing all of our specs at this point. 111 00:05:44,801 --> 00:05:46,890 So I'm gonna save this index.js file, 112 00:05:46,890 --> 00:05:49,590 and we're gonna come back over to index_test 113 00:05:49,590 --> 00:05:53,073 and at the top, we'll import save_comment from, 114 00:05:55,710 --> 00:05:58,402 and this is gonna be a little bit of a nightmare, 115 00:05:58,402 --> 00:06:01,710 we're gonna go up twice into source, into actions, 116 00:06:01,710 --> 00:06:03,363 and we're gonna get types. 117 00:06:04,722 --> 00:06:08,610 So we'll go up twice into source, into actions, 118 00:06:08,610 --> 00:06:10,060 and then we'll get our types. 119 00:06:11,838 --> 00:06:14,138 Next, we'll get our action creator savecomment 120 00:06:15,120 --> 00:06:20,120 from up, up, into source, and then into actions. 121 00:06:21,630 --> 00:06:24,873 And because our actions file is called index.js, 122 00:06:28,199 --> 00:06:31,767 wpack will throw on the index.js for us for free, 123 00:06:31,767 --> 00:06:33,330 so we don't have to put that on 124 00:06:33,330 --> 00:06:35,530 just because it's called specifically index. 125 00:06:36,780 --> 00:06:39,570 Okay, so we've not got really all the pieces here 126 00:06:39,570 --> 00:06:40,520 that we care about. 127 00:06:41,487 --> 00:06:43,140 We've got the type, we've got the action creator, 128 00:06:43,140 --> 00:06:45,000 we can really write some expectations 129 00:06:45,000 --> 00:06:46,740 to meet both of these specs. 130 00:06:46,740 --> 00:06:49,950 So again, I'm going to encourage you to pause the video 131 00:06:49,950 --> 00:06:53,280 and put together some expectations for each of these, 132 00:06:53,280 --> 00:06:54,663 these two it blocks. 133 00:06:55,548 --> 00:06:57,780 I think that we can get away with just a single expectation 134 00:06:57,780 --> 00:07:01,053 in both cases and I recommend you to give it a shot. 135 00:07:01,970 --> 00:07:05,040 So if you want to take a go at it, go for it now, 136 00:07:05,040 --> 00:07:10,040 otherwise, we're gonna go ahead and do the implementation. 137 00:07:12,630 --> 00:07:14,910 Okay, so for the correct type, 138 00:07:14,910 --> 00:07:19,440 we'll say that we expect savecomment, when it gets called, 139 00:07:19,440 --> 00:07:21,240 it's gonna return our action, right? 140 00:07:22,247 --> 00:07:24,428 So let's pull that out to a helper. 141 00:07:24,428 --> 00:07:26,383 We'll say const action savecomment. 142 00:07:28,546 --> 00:07:32,917 Now, I expect action.type to equal save_comment. 143 00:07:34,546 --> 00:07:36,240 So really straightforward spec, 144 00:07:36,240 --> 00:07:37,863 we call the action creator, 145 00:07:38,887 --> 00:07:41,160 we don't have to pass anything in, totally optional, 146 00:07:41,160 --> 00:07:43,860 all we care about is that the action we get back 147 00:07:43,860 --> 00:07:46,200 should have the correct type, 148 00:07:46,200 --> 00:07:48,933 the same type that we imported from our types file. 149 00:07:50,700 --> 00:07:52,860 Now, the second one is gonna be a little bit more tricky 150 00:07:52,860 --> 00:07:55,680 because we have to think about exactly how 151 00:07:55,680 --> 00:07:58,893 we want to put this action creator together. 152 00:08:00,226 --> 00:08:04,020 So in this case, we'll say const action savecomment, 153 00:08:04,020 --> 00:08:07,050 and I'm going to assume, this is a total assumption, 154 00:08:07,050 --> 00:08:09,660 that the comment that we want to save will be passed 155 00:08:09,660 --> 00:08:12,360 as an argument to savecomment. 156 00:08:12,360 --> 00:08:15,868 So I'm gonna say that I'm gonna pass the comment 157 00:08:15,868 --> 00:08:19,353 that I want to save as an argument, so we'll do new comment. 158 00:08:21,030 --> 00:08:24,940 Now, I'm going to expect that the action payload 159 00:08:26,763 --> 00:08:30,063 will equal new comment. 160 00:08:31,496 --> 00:08:33,942 So again, not too crazy a spec. 161 00:08:33,942 --> 00:08:37,861 We call save_comment, it's gonna return an action, 162 00:08:37,861 --> 00:08:39,840 and then we just assert that the payload of the action 163 00:08:39,840 --> 00:08:42,273 is equal to the string new comment. 164 00:08:43,921 --> 00:08:45,521 So let's go ahead and save this. 165 00:08:47,163 --> 00:08:49,323 We just created this spec file so remember, 166 00:08:49,323 --> 00:08:50,902 whenever you create a new spec file, 167 00:08:50,902 --> 00:08:52,982 we have to restart mocha. 168 00:08:52,982 --> 00:08:57,570 So let's close the process with control+C, 169 00:08:57,570 --> 00:08:59,223 and then we'll start it back up, 170 00:09:05,070 --> 00:09:07,819 and we get our two failures here. 171 00:09:07,819 --> 00:09:09,690 So cannot read property type of undefined, 172 00:09:09,690 --> 00:09:12,153 cannot read property payload of undefined, 173 00:09:13,114 --> 00:09:15,512 and so these errors really make sense because right now, 174 00:09:15,512 --> 00:09:17,670 we're not returning anything from the action creator. 175 00:09:17,670 --> 00:09:20,910 So action in this case is undefined, 176 00:09:20,910 --> 00:09:24,420 and we're trying to read type of undefined, 177 00:09:24,420 --> 00:09:25,920 which is gonna throw an error. 178 00:09:27,510 --> 00:09:29,310 Okay, so these specs look pretty good. 179 00:09:29,310 --> 00:09:31,710 Let's go ahead and take care of the implementation 180 00:09:31,710 --> 00:09:33,123 inside of the next section.