Как проверить обновление состояния в компоненте функции? (состояние в родительском компоненте, обновить логи c в дочернем) - PullRequest
0 голосов
/ 02 марта 2020

У меня есть функции с именем 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

1 Ответ

0 голосов
/ 03 марта 2020

ОК, поэтому после некоторого поиска в Google я обнаружил, что в настоящее время невозможно проверить состояние компонента функции с помощью Jest / Enzyme.

Например, функция тестирования state(), которую предоставляет Enzyme, только для компонентов класса ...

...