如何将待办事项列表对象传递给测试文件以覆盖初始状态?

How can I pass todo list object to test file to override initial state?

这是一个非常普遍的问题,在网络上解决的结果很少。我尝试测试使用 useContext 挂钩的 Statistics 组件。在隔离模式下测试 运行s 它总是捕获空数组,我无法传递我的待办事项列表对象。

我正在尝试 运行 测试但失败了

FAIL src/components/Statistics/__test__/Statistics.test.js (5.23 s)
  ● Testing Statistics Component › should return valid complete amount and due tasks count

    expect(element).toHaveTextContent()

    Expected element to have text content:
      3
    Received:
      0

      36 |
      37 |     const completedCount = screen.getByTestId("completed-count");
    > 38 |     expect(completedCount).toHaveTextContent(3);
         |                            ^
      39 |
      40 |     const dueTaskCount = screen.getByTestId("due-todo");
      41 |     expect(dueTaskCount).toHaveTextContent(1);

我的上下文代码

export const TodoContext = createContext(null);

function TodoContextProvider(props) {
  const initialState = []
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <TodoContext.Provider value={{ state, dispatch }}>
      {props.children}
    </TodoContext.Provider>
  );
}

export default TodoContextProvider;

我的统计组件

function Statistics() {
  const { state } = useContext(TodoContext);

  const completedTodo = todos?.filter((item) => item.complete === true);
  const dueTodos = todos?.filter((item) => new Date(item.due) < new Date());

  return (
    <Row className="m-1 p-4">
      <Col>
        <h2 className="text-primary text-center">My ToDo Statistics</h2>
        <p className="text-center">
          Completed: <span data-testid="completed-count">{completedTodo?.length}</span> |
          Due: <span data-testid="due-todo">{dueTodos?.length}</span>
        </p>
      </Col>
    </Row>
  );
}

export default Statistics;

最后是我的统计测试文件

describe("Testing Statistics Component", () => {
  it("should return valid complete amount and due tasks count", () => {
    render(
      <TodoContextProvider>
        <Statistics />
      </TodoContextProvider>
    );

    const completedCount = screen.getByTestId("completed-count");
    expect(completedCount).toHaveTextContent(3);

    const dueTaskCount = screen.getByTestId("due-todo");
    expect(dueTaskCount).toHaveTextContent(1);
  });
});

这是待办事项列表项

const todos = [
  {
    todo: "Take a note",
    due: "2022-04-01",
    id: 1648874401775,
    complete: true,
    order: 1,
  },
  {
    todo: "Brush teeth",
    due: "2022-04-13",
    id: 1648874401776,
    complete: true,
    order: 2,
  },
  {
    todo: "Go to bed",
    due: "2022-04-23",
    id: 1648874401777,
    complete: true,
    order: 3,
  },
];

我分析你的代码。让我们快速 运行 我检测到的主要问题。

  1. TodoContextProvider 不可扩展。封装性强。
  2. 在 Statistics 测试文件中,您没有提供 (todos) 个状态值。上下文哪里需要接受它?
  3. 请注意 - 始终需要包装所有应用程序的库创建自定义渲染。如下例所示。

import { render } from "@testing-library/react";
import { todoContext } from "../context/TodoContext";

const customRender = (ui, { providerProps, ...renderOptions }) => {
  return render(
    <todoContext.Provider {...providerProps}>{ui}</todoContext.Provider>,
    renderOptions
  );
};

export { customRender as render };

Source

我创建了额外的文件来测试实用程序。命名为testing-library-utils.jsx。并从那里导入渲染。

import { screen, waitFor } from "@testing-library/react";
import Statistics from "../Statistics";
import { render } from "../../../test-utils/testing-library-utils";

const todos = [
  {
    todo: "Take a note",
    due: "2022-04-01",
    id: 1648874401775,
    complete: true,
    order: 1,
  },
  {
    todo: "Brush teeth",
    due: "2022-04-13",
    id: 1648874401776,
    complete: true,
    order: 2,
  },
  {
    todo: "Go to bed",
    due: "2022-04-23",
    id: 1648874401777,
    complete: true,
    order: 3,
  },
];

describe("Testing Statistics Component", () => {
  it("should return valid complete amount and due tasks count", () => {

    const providerProps = {
      value: {
        state: todos,
      },
    };

    render(<Statistics />, { providerProps });

    const completedCount = screen.getByTestId("completed-count");
    waitFor(() => expect(completedCount).toHaveTextContent(3)).then();
  });
});

就我而言,所有测试都通过了。 我建议您在开始编写任何测试之前了解 React 中的测试概念。