Adding tests for TodoList

We'll start off by adding a framework to put the rest of our TodoList tests on! We'll need our standard imports and tests for rendering, snapshots, and shallow components! We'll start off with this scaffold for src/TodoList.test.js:

import React from "react";
import ReactDOM from "react-dom";
import { shallow } from "enzyme";
import renderer from "react-test-renderer";

import TodoList from "./TodoList";
import NewTodo from "./NewTodo";
import Todo from "./Todo";

describe(TodoList, () => {
const component = shallow(<TodoList />);

it("renders without crashing", () => {
const div = document.createElement("div");
ReactDOM.render(<TodoList />, div);
ReactDOM.unmountComponentAtNode(div);
});

it("renders and matches our snapshot", () => {
const component = renderer.create(<TodoList />);
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});

it("renders a TodoList component", () => {
expect(component.contains(<div className="TodoList" />));
});
});

We covered these tests previously, so there's not much we'll need to jump into, but we will want to make sure that, since our render() call includes a NewTodo component and we've imported that component at the top of our file, we have a test that verifies there's a single NewTodo in the tree:

  it("includes a NewTodo component", () => {
expect(component.find(NewTodo)).toHaveLength(1);
});

We'll also need to verify how many Todo components appear in our TodoList, but there's a little bit of a more complicated problem we have to solve with this test. If you remember, the state's "items" property in TodoList determines what Todos should appear, so we'll check the state versus the component's find function to see that the two are in sync with each other:

  it("renders the correct number of Todo components", () => {
const todoCount = component.state("items").length;
expect(component.find(Todo)).toHaveLength(todoCount);
});

Our component already gets rendered out via the shallow() call, so we'll use the state() call to verify the length of the items and find the equal number of Todo components. We'll also need to test our addTodo function of TodoList:

  it("adds another Todo when the addTodo function is called", () => {
const before = component.find(Todo).length;
component.instance().addTodo("A new item");
const after = component.find(Todo).length;
expect(after).toBeGreaterThan(before);
});

There's some new functionality in here that might be slightly complicated, so let's talk a little bit about it! We start off by finding out how many Todos already exist, since after we add another item we should expect that to be what we started with, plus another one! After that, we'll want to call addTodo() on the component, but to do that we need to jump down into the actual living context of component. We can do that via the instance() call, which allows us to call any function on the component without having to simulate any button clicks! After we call addTodo, we grab the list of all of the Todos that exist on the function and expect it to be more than what we originally started with! This is a really important and great way to write our tests; we never hardcode the number of Todos or anything else; instead, we check relative values after events happen! This eliminates weird scenarios where someone changes the default or initial state for our components and breaks our tests as a direct result!

Finally, we need to implement a removeTodo test, which is just the reverse operation from the test we previously wrote:

  it("removes a Todo from the list when the remove todo function is called", () => {
const before = component.find(Todo).length;
const removeMe = component.state("items")[0];
component.instance().removeTodo(removeMe);
const after = component.find(Todo).length;
expect(after).toBeLessThan(before);
});

The only notable difference is the fact that removeTodo needs an actual item to remove, so we have to grab one of the items out of the list and remove that specifically by passing that value into the removeTodo function!

After all is said and done, we should have a full test suite for TodoList.test.js that looks like this:

import React from "react";
import ReactDOM from "react-dom";
import { shallow } from "enzyme";
import renderer from "react-test-renderer";

import TodoList from "./TodoList";
import NewTodo from "./NewTodo";
import Todo from "./Todo";

describe(TodoList, () => {
const component = shallow(<TodoList />);

it("renders without crashing", () => {
const div = document.createElement("div");
ReactDOM.render(<TodoList />, div);
ReactDOM.unmountComponentAtNode(div);
});

it("renders and matches our snapshot", () => {
const component = renderer.create(<TodoList />);
const tree = component.toJSON();
expect(tree).toMatchSnapshot();
});

it("renders a TodoList component", () => {
expect(component.contains(<div className="TodoList" />));
});

it("includes a NewTodo component", () => {
expect(component.find(NewTodo)).toHaveLength(1);
});

it("renders the correct number of Todo components", () => {
const todoCount = component.state("items").length;
expect(component.find(Todo)).toHaveLength(todoCount);
});

it("adds another Todo when the addTodo function is called", () => {
const before = component.find(Todo).length;
component.instance().addTodo("A new item");
const after = component.find(Todo).length;
expect(after).toBeGreaterThan(before);
});

it("removes a Todo from the list when the remove todo function is called", () => {
const before = component.find(Todo).length;
const removeMe = component.state("items")[0];
component.instance().removeTodo(removeMe);
const after = component.find(Todo).length;
expect(after).toBeLessThan(before);
});
});
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.200.66