У меня есть функции с именем changeStatus и deleteItem в компоненте TodoItem. js
Когда кнопка (с className из btn-info ) щелкается, вызывается функция changeStatus , которая изменяет состояние завершенного элемента todo на противоположное (значение по умолчанию - false, поэтому оно должно перейти в true).
При нажатии кнопки (с именем класса btn-danger ) вызывается функция deleteItem , которая удаляет элемент из массива задач.
Состояние элемента todo находится в приложении. js, откуда массив todos и функция setTodos передаются в TodoItemList, который визуализирует компонент TodoItem и передает todos и setTodos вплоть до TodoItem.
import React, { useState } from "react";
import AddItemBar from "./components/AddItemBar";
import TodoItemList from "./components/TodoItemList";
import "./App.css";
import { v4 as uuidv4 } from "uuid";
const App = () => {
// Initial state for todos
const [todos, setTodos] = useState([
{ id: uuidv4(), name: "Learn React", complete: false },
{ id: uuidv4(), name: "Graduate from school", complete: false },
{ id: uuidv4(), name: "Get a cool web development job", complete: false },
{ id: uuidv4(), name: "Learn more new technologies", complete: false },
{ id: uuidv4(), name: "Enjoy working life", complete: false }
]);
return (
<div className="container appbox">
<TodoItemList todos={todos} setTodos={setTodos} />
<AddItemBar todos={todos} setTodos={setTodos} />
</div>
);
};
export default App;
TodoItemList просто перебирает массив todos и отображает TodoItem для каждого элемента массива, передавая отдельный todo, массив todos и функцию setTodos в TodoItem:
import React from "react";
import TodoItem from "./TodoItem";
const TodoItemList = ({ todos, setTodos }) => {
var items = [];
// Create todo item list
todos.forEach(todo => {
items.push(
<TodoItem key={todo.id} todo={todo} todos={todos} setTodos={setTodos} />
);
});
return items;
};
export default TodoItemList;
TodoItem. js компонент:
import React from "react";
const TodoItem = ({ todo, todos, setTodos }) => {
// Todo item color and text changes based on todo.complete state
var color = todo.complete === true ? "lightgreen" : "bisque";
var text = todo.complete === true ? "Complete" : "Incomplete";
// Change completed status for clicked item
const changeStatus = id => {
var todoItems = todos.slice();
for (let i = 0; i < todos.length; i++) {
if (todoItems[i].id === id) {
var newComplete = !todoItems[i].complete;
todoItems[i].complete = newComplete;
}
}
setTodos(todoItems);
};
// Remove todo item
const deleteItem = id => {
const newTodos = [...todos];
var removeIndex = newTodos
.map(todo => {
return todo.id;
})
.indexOf(id);
newTodos.splice(removeIndex, 1);
setTodos(newTodos);
};
return (
<div
className="row mt-2 mr-1 ml-1 todoItem"
style={{ backgroundColor: color }}
>
<h5 className="col-sm text-center">{todo.name}</h5>
<button
className="btn btn-info col-sm-3"
onClick={() => changeStatus(todo.id)}
>
{text}
</button>
<button
className="btn btn-danger col-sm-2"
onClick={() => deleteItem(todo.id)}
>
Delete
</button>
</div>
);
};
export default TodoItem;
Теперь, как мне проверить побочные эффекты этих функций в TodoItem?
Вот TodoItem.test. Пока что файл js проверяет только пользовательский интерфейс (все они проходят), но не обновляет состояние:
import React from "react";
import TodoItem from "./TodoItem";
import { v4 as uuidv4 } from "uuid";
import { shallow } from "enzyme";
describe("<TodoItem />", () => {
it("should render without problems", () => {
const todo = { id: uuidv4(), name: "Learn React", complete: false };
shallow(<TodoItem todo={todo} />);
});
it("shallow wrapper instance should be null", () => {
const todo = { id: uuidv4(), name: "Learn React", complete: false };
const wrapper = shallow(<TodoItem todo={todo} />);
const instance = wrapper.instance();
expect(instance).toEqual(null);
});
it("should have todo text", () => {
const todo = { id: uuidv4(), name: "Learn React", complete: false };
const wrapper = shallow(<TodoItem todo={todo} />);
expect(wrapper.find("h5").length).toEqual(1);
});
it("should have a complete button", () => {
const todo = { id: uuidv4(), name: "Learn React", complete: false };
const wrapper = shallow(<TodoItem todo={todo} />);
expect(wrapper.find("button.btn-info").length).toEqual(1);
});
it("should have a delete button", () => {
const todo = { id: uuidv4(), name: "Learn React", complete: false };
const wrapper = shallow(<TodoItem todo={todo} />);
expect(wrapper.find("button.btn-danger").length).toEqual(1);
});
});
Я читал, что было бы вредно тестировать сами функции напрямую,
, поэтому я хочу просто проверить побочные эффекты:
- changeStatus : проверить, изменяется ли todo.complete с false до true
- deleteItem : проверить, удаляется ли элемент из todos array