我是第一次try 单元测试. 我想测试渲染模式或对话框的功能,视情况而定.

我看过无数的帖子和视频,但从来没有见过像我这样的 case . 在我的模型中,我看到了Udemy,并实现了马克西米利安·施瓦茨米勒的课程.

这是我引用的一段视频的YouTube链接. https://youtu.be/To2PzUT1lQ4?si=MYC_E_i_S2jafa-z

这是另一个问题,但这是props ,我没有使用props 条件组件 How to test conditional rendering of components using Jest and Enzyme

我认为这是最相似的问题,但我很难把它应用到我的 case 中. testing conditional rendering that relies on state using react testing library

https://medium.com/@manojmukherjee777/react-testing-library-portal-modal-b05aaeb5dda7

《测试顺序》

  1. 呈现FetchRenderTest

  2. 点击"测试开始"按钮

  3. 正在运行FETCHMOCK

  4. 假设对响应的请求或通信失败. 因此将isError更改为True

  5. 渲染Errormodal.tsx<-我不知道如何处理此部分. (再解释一遍-错误模式是如上所述出现在屏幕上的模式或对话.)

  6. "错误对话框关闭"按钮正在验证渲染

我的代码在这里

FetchRenderTest.tsx

import React, { useState, Fragment } from "react";

import ErrorModal from "./UI/ErrorModal";

function FetchRenderTest() {
  const [isError, setIsError] = useState(false);
  const errorHandler = () => {
    setIsError(false);
  };

  const confirmHandler = async () => {
    let domain = window.location.hostname;
    try {
      const response = await fetch("<this is url>", {
        method: "PUT",
        headers: {
          "Content-type": "application/json",
        },
        body: JSON.stringify({ SendData: "test" }),
      });

      if (response.status === 200) {
        return;
      } else {
        setIsError(true);
        return;
      }
    } catch (error) {
      setIsError(true);
    }
  };
  return (
    <>
      {isError && <ErrorModal role="dialog" title="Modal, Dialog Test" message="" onConfirm={errorHandler} />}
      <div>
        <button onClick={confirmHandler}> Testing Start</button>
      </div>
    </>
  );
}

export default FetchRenderTest;


ErrorModal.tsx

import React, { Fragment } from "react";
import ReactDOM from "react-dom";
import PopupDragControl from "./PopupDragControl";
import Button from "./Button";
import classes from "./ErrorModal.module.css";

const ErrorModalOverlay = (props: any) => {
  return (
    <div>
      <div className={classes.backdrop} />
      <PopupDragControl>
        <header className={classes.header}>
          <h2>{props.title}</h2>
        </header>
        <div className={classes.content}>
          <p>{props.message}</p>
        </div>
        <footer className={classes.action}>
          <Button onClick={props.isConfirm}> Error dialog close </Button>
        </footer>
      </PopupDragControl>
    </div>
  );
};

const portalElement = document.getElementById("overlays"); <- I tried the "root" 
const ErrorModal = (props: any) => {
  const { title, message, onConfirm } = props;
  if (!portalElement) {
    return null;
  }
  const messageText = message ? message.result : null;
  const errorModalElements = ReactDOM.createPortal(<ErrorModalOverlay title={title} message={messageText} isConfirm={onConfirm}></ErrorModalOverlay>, portalElement);

  return <Fragment>{errorModalElements}</Fragment>;
};

export default ErrorModal;

Button.tsx

const Button = (props : any) => {
  return (
    <button
      type={props.type || "button"}
      className={`${classes.button} ${props.className}`}
      onClick={props.onClick}
      disabled={props.disabled}
    >
      {props.children}
    </button>
  );
};

export default Button;

和测试代码 FetchRenderTest.test.tsx

import React from "react";
import { render, screen, fireEvent, waitFor } from "@testing-library/react";
import "@testing-library/jest-dom";

import FetchRenderTest from "./FetchRenderTest";

test("renders learn react link", async () => {
  global.fetch = jest.fn().mockRejectedValueOnce({
    json: jest.fn().mockRejectedValueOnce({ success: true }),
    ok: true,
    status: 500,
  });

  render(<FetchRenderTest />);

  fireEvent.click(screen.getByText(/Testing Start/i, { exact: false }));

  await waitFor(() => {
    expect(global.fetch).toHaveBeenCalledWith("<this is url>", {
      method: "PUT",
      headers: {
        "Content-type": "application/json",
      },
      body: JSON.stringify({ SendData: "test" }),
    });
  });
fireEvent.click(screen.getByText(/Error dialog close/i, { exact: false }));
});

coverlage image

从其中一次try 中得到的 idea Reaction的默认设置此外,不是所有渲染的通道 渲染到.

我猜问题出在id上,所以我将其全部修改为根,但它仍然无法测试.

我用谷歌查找了所有常用的方法,但它不适合我的情况.

搜索方法可能不是很好.

在这种情况下,如果您必须单独测试每个组件,请让我知道

推荐答案

在您的测试代码中,您是在正确的轨道上.点击"错误对话框关闭"按钮后,您需要模拟FETCH请求、呈现、断言.以下是修改测试以实现这一点的方法:

完整的代码添加您的代码和测试文件.请跑npm run test https://stackblitz.com/~/github.com/2manoj1/example-model-test-vitest

如果要在本地运行: 在回购下克隆 https://github.com/2manoj1/example-model-test-vitest

npm i. npm run test or npm run test:ui.

运行项目 npm run dev

使用[MSW][1]

// FetchRenderTest.test.js

import {
    render,
    screen,
    userEvent,
    waitFor,
    debug,
    act,
} from "./utils/test-utils";
import { http, HttpResponse } from "msw";
import { setupServer } from "msw/node";
import FetchRenderTest from "./FetchRenderTest";

const handlers = [
    http.put("https://65d1ac70987977636bfb57a9.mockapi.io/api/v1/test", () => {
        return HttpResponse.json({ msg: "Invalid request" }, { status: 400 }); // Simulate error response
    }),
];
const server = setupServer(...handlers);

beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

test("renders ErrorModal when fetch fails", async () => {
    render(<FetchRenderTest />, { container: document.body });

    const testingStartButton = screen.getByText("Testing Start");
    await act(async () => {
        // Click the button to trigger the fetch request
        await userEvent.click(testingStartButton);
    });

    // Wait for the ErrorModal to render
    await waitFor(() => {
        const errorModal = screen.getByRole("dialog");
        expect(errorModal).toBeInTheDocument();
    });

    // Verify the modal content
    const modalTitle = screen.getByText("Modal, Dialog Test");
    expect(modalTitle).toBeInTheDocument();

    // Verify the close button is rendered
    const closeButton = screen.getByRole("button", {
        name: /Error dialog close/i,
    });
    expect(closeButton).toBeInTheDocument();
});

这项测试:

  1. 设置MSW截取请求并模拟状态代码为500的失败请求.
  2. 呈现FetchRenderTest组件.
  3. 点击[测试开始]按钮,触发抓取请求.
  4. 等待呈现错误模式,并断言它包含预期的标题和关闭按钮.
  5. 单击错误模式上的关闭按钮.
  6. 等待从文档中删除错误模式.

此测试确保组件在FETCH请求失败时正确运行,显示错误模式并允许用户关闭它.

Reactjs相关问答推荐

CSS转换不适用于React MUI对象

MUImaterial -ui-如何将文本字段和 Select 分组?

react-hook-form问题:为什么getValues不返回大多数当前值?

在迁移到Redux—Toolkit 2.0和Redux5.0之后,我在extraReducer和Slice方面有点挣扎,

导致类型错误的调度不是函数";

404使用GitHub操作部署Next.js应用程序时出错

REACTJS:在Reaction中根据路由路径更改加载器API URL

如何在单击行中的图标时避免选中ionic 复选框?

如何从Reaction-Arborist树获取排序数据

获取类别和页面的参数

设置自定义形状的纹理

使用获取的数据更新状态,但在try console.log 时它给出未定义

我发送的 prop 的值不会改变.如果成功登录,导航栏中的 prop 必须为 true.我从后端得到 200 ok

React中的功能性组件克隆优化

如何在 React 过滤器中包含价格过滤器逻辑?

Zod 验证模式根据另一个数组字段使字段成为必需字段

状态链接未传递到路由页面

无法读取未定义的react native 的属性参数

如何解决在 react.js 中找不到模块错误

理解 React 中的 PrevState