Teacher: So the react side of our application
is in a pretty good spot.
We have three components: app, comment box,
and comment list, and each of those is pretty well tested
through and through.
The next thing that we need to do
is we need to work on the redux side of things.
So we don't have any specs around the redux side of things
right now and without redux,
we don't really have the ability
to save any of our comments or to communicate those comments
that are saved over to the comment list component.
So we need to first make an action creator
to save each comment as it gets created,
and we also need to make a reducer
to collect all of those comments as they're created.
The comments reducer will be responsible for creating
the comments piece of application state as well.
So let's get started by first making our action creator.
We'll first make a new directory inside of our test folder
for holding our action spec file.
So we'll make a new folder called actions,
and right now inside of our actions folder
inside of our source directory,
we've got an existing actions file called just index
and we're gonna end up putting
all of our action creators in here.
So just to mirror that folder structure one for one,
we're going to create a test file
inside of our test actions directory
and we'll call it index_test.
Now, index_test for a filename is pretty goofy,
if you want to call this actions_test
or something like that instead,
I am whole heartedly behind that,
going with index_test is a little bit strange.
Nonetheless, we're doing it because it is a one to one
mapping with our implementation directory.
So we'll import that file versus you will create that file,
and then inside of here we're ready to write a spec
around our action creator.
So we're going to do this 100% with test driven development
or behavior driven development.
So we're not gonna write a single piece of code
inside of our implementation file, index.js,
we're going to write specs first
and then we'll do the implementation
after we've written all of our specs.
In practice here, the testing action creators
tends to be pretty straightforward
so this shouldn't be too too bad.
So at the top, as with all of our specs,
we need to import some helpers from our test helper file
called test_helper.js.
So we'll import expect from test_helper
and in the other specs we wrote,
we also imported the render component helper as well.
In this case, we're not rendering any components,
we're just testing a action creator
so we don't need that render component helper here.
We're going to describe the actions, all of our actions,
and the action that we're going to test in particular
is a savecomment action creator.
So when we're testing our action creators,
because a lot of the time they'll all just fit
inside of one file, I like to make
a top level describe that says hey,
here's all the actions we're about to test,
and then I make one describe for each action creator,
and inside of here, we can put our various it blocks.
So the first thing I want to make an assertion about,
and this is where we're kind of deviating
from the same culture that we had
around the react side of things
where we were just making assertions about the HTML
or the end product, when we're testing action creators,
we tend to be a little bit more precise
and test it a little lower level.
So we're going to expect that it has the correct type
and it has the correct payload as well.
So we're being very particular here in implementation.
So for our first it block, we'll say it has the correct type
and then we'll also say it has the correct payload.
So I've been saying we're testing our action creators,
but really we're testing the action
that's returned from the action creator.
So we're going to assert both the type and the payload
on the action that gets returned.
So this looks like a pretty good
testing structure right here, what we haven't done yet
is we haven't imported the action creator at the top,
so we should probably at least start to scaffold out
our action creator before we go any further.
Before we make any action creators,
we have to make a type for our action.
So inside of the actions folder,
we'll make a new file, types.js,
and we'll end up just sticking
all of our action types inside of here.
For application, we're only gonna have one type
and it's gonna be just the save_comment type.
So we'll export const save_comment, save_comment.
So now we can make use of this type
inside of our action creator over in source,
actions, index.js.
So over here we can import save_comment from types,
and then we can export our function savecomment,
this is gonna be our action creator like so.
So now we've scaffolded this stuff out,
we can really finish writing all of our specs at this point.
So I'm gonna save this index.js file,
and we're gonna come back over to index_test
and at the top, we'll import save_comment from,
and this is gonna be a little bit of a nightmare,
we're gonna go up twice into source, into actions,
and we're gonna get types.
So we'll go up twice into source, into actions,
and then we'll get our types.
Next, we'll get our action creator savecomment
from up, up, into source, and then into actions.
And because our actions file is called index.js,
wpack will throw on the index.js for us for free,
so we don't have to put that on
just because it's called specifically index.
Okay, so we've not got really all the pieces here
that we care about.
We've got the type, we've got the action creator,
we can really write some expectations
to meet both of these specs.
So again, I'm going to encourage you to pause the video
and put together some expectations for each of these,
these two it blocks.
I think that we can get away with just a single expectation
in both cases and I recommend you to give it a shot.
So if you want to take a go at it, go for it now,
otherwise, we're gonna go ahead and do the implementation.
Okay, so for the correct type,
we'll say that we expect savecomment, when it gets called,
it's gonna return our action, right?
So let's pull that out to a helper.
We'll say const action savecomment.
Now, I expect action.type to equal save_comment.
So really straightforward spec,
we call the action creator,
we don't have to pass anything in, totally optional,
all we care about is that the action we get back
should have the correct type,
the same type that we imported from our types file.
Now, the second one is gonna be a little bit more tricky
because we have to think about exactly how
we want to put this action creator together.
So in this case, we'll say const action savecomment,
and I'm going to assume, this is a total assumption,
that the comment that we want to save will be passed
as an argument to savecomment.
So I'm gonna say that I'm gonna pass the comment
that I want to save as an argument, so we'll do new comment.
Now, I'm going to expect that the action payload
will equal new comment.
So again, not too crazy a spec.
We call save_comment, it's gonna return an action,
and then we just assert that the payload of the action
is equal to the string new comment.
So let's go ahead and save this.
We just created this spec file so remember,
whenever you create a new spec file,
we have to restart mocha.
So let's close the process with control+C,
and then we'll start it back up,
and we get our two failures here.
So cannot read property type of undefined,
cannot read property payload of undefined,
and so these errors really make sense because right now,
we're not returning anything from the action creator.
So action in this case is undefined,
and we're trying to read type of undefined,
which is gonna throw an error.
Okay, so these specs look pretty good.
Let's go ahead and take care of the implementation
inside of the next section.