Check out a free preview of the full Advanced Redux with Redux Toolkit course

The "Unit Testing Redux" Lesson is part of the full, Advanced Redux with Redux Toolkit course featured in this preview video. Here's what you'd learn in this lesson:

Steve writes unit tests for testing slices in the application. The slice methods are imported. The initial state is defined, and the actions in each slice are tested.

Preview
Close

Transcript from the "Unit Testing Redux" Lesson

[00:00:00]
>> So unit testing may give you the moral of the story first. It's very easy, because as I've alluded to repeatedly, at the end of the day, it's a function. You put stuff and there's not like for a certain amount of component, and then you have to simulate a click on that button and then you have to, Function, call it you set it up and so like there's a patterns around it, but generally speaking it is like pretty elegant and one of the reasons.

[00:00:38]
And I will just kind of lay this seed now, so I can like, reference it later. When you have stuff like promises, normally what happens is the promise is separate from this entire process. It what you might kick off in action when you initiate the request. That's usually when you put up the loader, stuff along those lines.

[00:00:59]
And then you will kick off another action when the request comes back, cool. But those are just plain old JavaScript objects that are getting dispatched, right? And so when you write your tests, you can just say, hey, if you ever hear that a promise was fulfilled, for the data from this API.

[00:01:17]
This is how I expect the state to have been updated with that data. If you hear that there was an error, if you here that we are in a loading state, this is what I expect the state of my shape to look like. And then like the reaction components are just based on those props.

[00:01:30]
So everything should be super easy at this point. I think sometimes we have a tendency cuz we have all these like. They do everything for your frameworks that you have been set up everything by keeping it like lightweight and simple. A lot of this becomes very simple. Let's just show an example.

[00:01:46]
I think it's worthwhile to talk about. So I would call it like task slice, and I'll probably do like one or two in task slice and like, we'll revisit it. And we make sure that the more the nuances between the two isn't the case, but it was in place that we have a frame of reference.

[00:02:05]
And so yeah, we probably, at this point, probably want the reducer from there, and I want the action. So I may just call much actions and make sure my state changes the way that I expect it to. And you'll kind of see how this looks, and then you just follow this pattern forward.

[00:02:23]
And it works out pretty great. So we can say tasksReducer, we're gonna need that. addTask, removeTask, those are the only two we have right now. Awesome, so those are kind of set up and ready to go. And then we should be able to say describe tasksSlice, and this is how it becomes incredibly easy.

[00:02:51]
I'll add one when we do some asynchronous stuff later. We'll put this in place and so then we say it should add a task when, and then do I see something cool. We'll switch it to a template string when the, So the way that that worked in those conditionals before, is that not only is the actual graters function have a type property, the two string method on it gives you the name of the action that it fires, right?

[00:03:32]
So this will be tasks/add task in this case. Awesome, and then a lot of times I will have like just some initial state ready to go. And so let's say const initial state, and I'll just use my did I not export it? Exported user. And that's why I had it above and out, like to your question earlier, so I can use it to set up test examples and have them ready to go.

[00:04:11]
It's good enough for, and like you could also, like, I. I might also then like because Redux stores everything in a JavaScript object, you could also just for my production projects. I have a bunch of different cases where things have bitten me before I grab that JSON. I throw that JSON file, I pull it in, and I write a bunch of tests around it, right?

[00:04:33]
So I also have a bunch of just JSON files, just in a directory in the repo where I have. Okay, here's a bunch of failed workflows and canceled workflows. And here was it looks like this weird state in that weird state. And I kind of like, iterate through all the cases to make sure my function takes every weird thing that I've ever seen is ready to go.

[00:04:52]
So here we say create task and that needs a title. All right, tests. Make them pass. Those seem like things I should do, right? Awesome, and so we have this in place. And then, again, you might choose to hard code these. I'm fine with this, but I appreciate and respect wanting to have static data in there as well.

[00:05:24]
So then we'd make that third task. Does anyone have an idea what it should be? Title write tests, make them pass, profit, sounds good. Then the action, With that task, and so I expect when it goes into the reducer, I am pretty confident that my action creators that came from Redux toolkit have been tested by them, right?

[00:06:04]
I don't feel the need to test the action creator. You can argue should I test my create task? Yeah, probably, but that's not even touching Redux, so you can do it on your own. We have that in place, and then the act of seeing if things change is super simple.

[00:06:22]
We can say, newState is, tasksReducer where you pass it in that initialState, and then the action, right? And we could expect that as like a three I'm actually gonna say that it has, He's on shift this time, right, expect that. A new state, That entities, right, to new state that yeah that was just that one scope, right?

[00:07:07]
To equal that new task I just made plus everything that was in the initial state. Initial State is written wrong now, that's gotta be entities. TypeScript would have yelled at me, I'm fine. And you could argue, yeah, I could do, initial state, Data entities, And then my new task in front of that, right?

[00:07:50]
So we'll spread that one out. Leave it, logic right on that, and then we should be able to. Here run test and it passes. Like that is a reducer test in this pattern and pulling it in because you've got the action creators already because you have everything. It is simply a unit test, as you know, in love without a ton of work and like you can be pretty confident, like have.

[00:08:23]
Getting the full test coverage in this world is a lot easier than in a lot of other cases. And this scales pretty well in terms of just like it is very easy to attempt, you can actually do test driven development with us and not hate yourself cuz it was all just regular JavaScript.

[00:08:40]
And this is like, you could do this with use reducer too, right? You don't have as many of the abstractions ready to go. But you can also use if you're like, we don't use Redux, I have used to do so all over the place. Then, these are patterns you can still use because the pattern is the same in this case, no matter what, right?

[00:08:56]
And so I will leave it as an exercise for the reader, so we can cover some other things in our time together, but this pattern plays out in terms of how you can go about testing. And like Ads a lot of confidence in a lot of cases, especially if I'm expecting stuff to transform, I can basically work out all these cases.

[00:09:15]
Any questions about that? And I will push this up on a branch as well.
>> You said testing the actions kind of pointless at this point.
>> Well, the action creator like, all I did was pass it like I'm using create act. I'm using create slice like that was made for me.

[00:09:35]
The action is I only wrote add task colon, and then the reducer logic. It made that task for me. I could test it, but I am working under the assumption that Redux toolkit has unit tests, right? And that I don't need to other than to show off. And I like showing off, but I don't feel super that I need to do that fact.

[00:10:01]
It's been tested, I don't need to do that. For me testing is the way I know that I don't have good enough tests. Is if I go to do a refactor and I have a pit of dread in my stomach, for me, it's a confidence game.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now