Sometimes our components are subscribed to a Redux store. This can make it difficult to test because it requires a mocked Redux store in order to render in our test files. In this lesson we talk about how we can test the core functionality of our component without the headache of mocking out Redux concepts.
Instructor: [00:00] I've got a simple todo list here. I'm able to click into this input box, write out todos, and then, when I click on the addTodo button, it'll add it to the list.
[00:08] Then, in order to delete them, we simply just need to click on them. We're using Redux to fire off the adding, removing, and keeping the current lists of our todos.
[00:18] Inside of our todo list component, we've got state here. That's going to keep track of our current input. Then we've also got three methods.
[00:26] The handleClick method attaches to our li todos and fires the removeTodoAction creator with the index to remove. The handleChange lives on the input to update our input state.
[00:38] The handleSubmit lives on the addTodo button, which calls the addTodoAction creator. This function sends off the current input state, and then clears the input.
[00:51] I've organized all of the Redux concepts into a store file. This is where our addTodo/removeTodoAction creators live. Then our reducer modifies the state according to our action creators.
[01:04] Then, finally, we export our store out. We use the provider and pass our store down through it. We've also got a todo list test file here where we can begin running our tests.
[01:17] When it comes to testing Redux components, as you can imagine, the biggest headache comes from trying to replicate a Redux store by mocking out its functionality. This ties our components to a lot of implementation detail when we really just want to test that our component renders and fires our prop actions.
[01:34] Instead of importing some library, we can import our component directly. This is bringing only our component into this file and not the connected higher order component that we're exporting here at the bottom by default.
[01:47] With this in mind, we can write out our game plan. Let's first test that it calls our addTodoAction when our button is clicked, it calls our removeTodo with an li click, and matches a snapshot.
[01:57] We'll write out a describe block for our todo list. Then, inside of this -- our first test -- it calls addTodo Redux action creator with button click. Now we need to make a props object with our addTodo and our todo list.
[02:13] Then we'll shallow render our todo list, spreading out our props. We'll find our input, and then simulate a change and pass through our mocked out event object with the value of buy groceries.
[02:29] Then we'll find our addTodo button class and simulate a click. We can expect that our props at addTodo is called with an object of text buy groceries.
[02:42] We created this props object with addTodo as a Jest mock function and a todos property with an empty array. This replicates our Redux store data.
[02:52] After finding both our input for adding input state and clicking of the addTodo button, we can assert that our addTodoAction creator is called with the right parameter.
[03:03] This test does pass. We can confirm that by messing with the text here, saving it, and reopening a terminal. We can see that everything is working correctly. I'll add that back.
[03:15] Now, for our next test, let's test that our removeTodoAction creator is called correctly. We'll say it calls removeTodoAction creator on li click. We'll make a new props object with removeTodo, jest.function, todos as an array of two todos.
[03:31] We'll say buy groceries is one and change our oil as our second. We'll wrapper shallow render our component, spreading out our new props.
[03:42] We'll find our lis, grab the first one, then simulate a click. Then expect that props.removeTodo to be called with zero.
[03:53] Similar to our last test, we're creating this props object. We're mocking out our removeTodoAction with Jest's mocking function.
[03:59] We've got two todos here. When we find our lis, we want to just delete the first one on the list. That'll be the buy groceries todo, and then we expect that our removeTodoAction is called with the right index which, in this case, is zero.
[04:17] We can double-check our terminal and see that our second new test also passes. We can make it fail by changing the zero to a one and changing it back.
[04:28] Perfect. We can finish up by creating a snapshot of this component. We'll say it matches snapshot, then we'll do const props as an object. Todos is an empty array. Const wrapper equals shallow our todo list, spreading our props.
[04:45] Then we'll expect that our two JSON wrapper matches a snapshot. Perfect, now we have a snapshot that's been written to our test suite.