没有自定义钩子的模拟测试

杨伟明
杨伟明
订阅者
278
文章
0
粉丝
测试交流1 180字数 554阅读1分50秒阅读模式
摘要我已经创建了一个基本的todolist组件,并正在为其编写一些测试,但我想知道如何模拟测试本地存储正在使用我当前拥有的代码收集数据,或者我是否会。。。

我已经创建了一个基本的todolist组件,并正在为其编写一些测试,但我想知道如何模拟本地存储正在使用我当前拥有的代码收集数据的测试,或者是否需要创建一个自定义钩子来模拟。理想情况下,我不想这样做,但感觉这将是使用渲染挂钩的唯一方法。

This is my current code for todolist:
import { useEffect, useState } from 'react';
import { Container, TextInput, Button, List } from '@mantine/core';
import { Tasks } from '../types';
const TodoList = () => {
  const [task, setTask] = useState('');
  const [todoList, setTodoList] = useState<Tasks[]>([]);
  const handleChange = (event: any): void => {
    setTask(event.target.value);
  };
  const handleDelete = (taskToDelete: any) => {
    const deleted = todoList.filter((t) => t.taskName !== taskToDelete);
    setTodoList(deleted);
    localStorage.setItem('localTasks', JSON.stringify(deleted));
  };
  useEffect(() => {
    if (localStorage.getItem('localTasks')) {
      const storedList = JSON.parse(localStorage.getItem('localTasks') || '{}');
      setTodoList(storedList);
    }
  }, []);
  const addTask = () => {
    const newTask = {
      taskName: task,
    };
    setTodoList([...todoList, newTask]);
    localStorage.setItem('localTasks', JSON.stringify([...todoList, newTask]));
    setTask('');
  };
  return (
    <Container>
      <TextInput
        type="text"
        name="task"
        placeholder="enter a task"
        onChange={handleChange}
        value={task}
      />
      <Button onClick={addTask} data-testid="add">
        Add Task
      </Button>
      {todoList.map((todo, key) => (
        <Container key={key}>
          <List
            data-testid="todos"
            icon={
              <Button
                onClick={() => {
                  handleDelete(todo.taskName);
                }}
              >
                X
              </Button>
            }
          >
            <List.Item>{todo.taskName}</List.Item>
          </List>
        </Container>
      ))}
    </Container>
  );
};
export default TodoList;

更新代码以将日期id添加到待办事项:文章源自玩技e族-https://www.playezu.com/179068.html

import { Button, Container, List, TextInput } from '@mantine/core';
import type { ChangeEvent } from 'react';
import { useEffect, useLayoutEffect, useRef, useState } from 'react';
const TodoList = () => {
  const isMounted = useRef(false);
  const [task, setTask] = useState('');
  const [todoList, setTodoList] = useState<Array<{ taskName: string; id: number }>>([]);
  const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
    setTask(event.target.value);
  };
  const handleDelete = () => {
    setTodoList((prevTodoList) => prevTodoList.filter((todo, index) => index !== todo.id));
  };
  const addTask = () => {
    setTodoList((prevTodoList) =>
      prevTodoList.concat({
        taskName: task,
        id: new Date().getTime(),
      }),
    );
    setTask('');
  };
  useLayoutEffect(() => {
    const localTasks = JSON.parse(localStorage.getItem('localTasks') || '[]');
    if (localTasks.length > 0) setTodoList(localTasks);
  }, []);
  useEffect(() => {
    if (isMounted.current) {
      localStorage.setItem('localTasks', JSON.stringify(todoList));
    } else {
      isMounted.current = true;
    }
  }, [todoList]);
  return (
    <Container aria-label="container">
      <TextInput
        type="text"
        name="task"
        placeholder="enter a task"
        onChange={handleChange}
        value={task}
      />
      <Button type="button" onClick={addTask} data-testid="add-todo" name="add-button">
        Add Task
      </Button>
      {todoList.map((todo, key) => (
        <Container key={key}>
          <List
            data-testid={`todo-${key}`}
            icon={
              <Button
                data-testid={`delete-todo-${todo.id}`}
                type="button"
                aria-label="delete-button"
                onClick={() => {
                  handleDelete(todo.id);
                }}
              >
                X
              </Button>
            }
          >
            <List.Item>{todo.taskName}</List.Item>
          </List>
        </Container>
      ))}
    </Container>
  );
};
export default TodoList;
文章源自玩技e族-https://www.playezu.com/179068.html文章源自玩技e族-https://www.playezu.com/179068.html
 
    • Matt Carlotta
      Matt Carlotta 9

      在这种情况下,我建议不要嘲笑 本地存储 而是按原样测试。
      托多利斯特。tsx公司
      import { Button, Container, List, TextInput } from "@mantine/core";
      import type { ChangeEvent, ReactElement } from "react";
      import { useEffect, useLayoutEffect, useRef, useState } from "react";

      const TodoList = (): ReactElement => {
      const isMounted = useRef(false);
      const [task, setTask] = useState("");
      const [todoList, setTodoList] = useState<Array<{ taskName: string }>>([]);

      const handleChange = (event: ChangeEvent<HTMLInputElement>): void => {
      setTask(event.target.value);
      };

      // filter by index instead of by value (duplicate values can exist)
      // ideally you would use uniquely generated ids instead of by index
      const handleDelete = (key: number): void => {
      setTodoList((prevTodoList) =>
      prevTodoList.filter((_t, idx) => idx !== key)
      );
      };

      // concatenate new task into the todo list
      // Array.concat() creates a new array
      const addTask = (): void => {
      setTodoList((prevTodoList) =>
      prevTodoList.concat({
      taskName: task,
      })
      );
      setTask("");
      };

      // on initial layout, update todo list if localTasks exist in 本地存储
      useLayoutEffect((): void => {
      const localTasks = JSON.parse(本地存储.getItem("localTasks") || "[]");
      if (localTasks.length > 0) setTodoList(localTasks);
      }, []);

      // on initial render, bypass updating local storage
      // on secondary/subsequent renders, update local storage with todoList
      useEffect((): void => {
      if (isMounted.current) {
      本地存储.setItem("localTasks", JSON.stringify(todoList));
      } else {
      isMounted.current = true;
      }
      }, [todoList]);

      return (
      <Container data-testid="container">
      <TextInput
      data-testid="task-input"
      type="text"
      name="task"
      placeholder="enter a task"
      onChange={handleChange}
      value={task}
      />
      <Button type="button" onClick={addTask} data-testid="add-todo">
      Add Task
      </Button>
      {todoList.map((todo, key) => (
      <Container key={key}>
      <List
      data-testid={`todo-${key}`}
      icon={
      <Button
      data-testid={`delete-todo-${key}`}
      type="button"
      onClick={() => {
      handleDelete(key);
      }}
      >
      X
      </Button>
      }
      >
      <List.Item>{todo.taskName}</List.Item>
      </List>
      </Container>
      ))}
      </Container>
      );
      };

      export default TodoList;

      托多利斯特。测验tsx公司
      import { fireEvent, render, screen } from "@testing-library/react";
      import TodoList from "./TodoList";

      describe("TodoList", () => {
      it("renders without errors", () => {
      render(<TodoList />);

      expect(screen.getByTestId("container")).toBeInTheDocument();
      });

      it("adds a task to the list and stores it to 本地存储", () => {
      render(<TodoList />);

      fireEvent.change(screen.getByTestId("task-input"), { target: { value: "123" } });

      fireEvent.click(screen.getByTestId("add-todo"));

      expect(screen.getByTestId("todo-0")).toBeInTheDocument();

      const localTasks = JSON.parse(本地存储.getItem("localTasks") || "[]");
      expect(localTasks).toEqual([{ taskName: "123" }]);
      });

      it("removes a task from the list and removes it from 本地存储", () => {
      render(<TodoList />);

      fireEvent.click(screen.getByTestId("delete-todo-0"));

      expect(screen.queryByTestId("todo-0")).not.toBeInTheDocument();

      const localTasks = JSON.parse(本地存储.getItem("localTasks") || "[]");
      expect(localTasks).toEqual([]);
      });
      });

      后果
      PASS src/托多利斯特。测验tsx公司
      TodoList
      ✓ renders without errors (82 ms)
      ✓ adds a task to the list and stores it to 本地存储 (23 ms)
      ✓ removes a task from the list and removes it from 本地存储 (10 ms)

      ————–|———|———-|———|———|——————-
      File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
      ————–|———|———-|———|———|——————-
      All files | 100 | 100 | 100 | 100 |
      托多利斯特。tsx公司 | 100 | 100 | 100 | 100 |
      ————–|———|———-|———|———|——————-

      Test Suites: 1 passed, 1 total
      Tests: 3 passed, 3 total
      Snapshots: 0 total
      Time: 1.073 s

    匿名

    发表评论

    匿名网友
    确定

    拖动滑块以完成验证