You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

微前端Dashboard应用Splitter组件单元测试及导入Mock问题

微前端中Dashboard应用对Utility组件的单元测试方案

问题背景

在微架构中,Utility应用封装了Splitter组件,Dashboard应用直接引入使用。当前在编写Dashboard的单元测试时,无法正确导入或Mock该Splitter组件,执行测试时报错。

相关代码

Dashboard.tsx(Dashboard应用)

import { LeftPanel, Splitter, axios } from "mycomponent";
import Home from "../Home/Home";
import { selectData } from "../../../constants/selectData";
import { Inventorytreeviewdata } from "../../../constants/treeData";
import { tabData } from "../../../constants/tabData";
import { rightComponentProps } from "../../../constants/ComponentProps";

export function DashBoard() {
  return (
    <Splitter
      LeftComponent={LeftPanel}
      leftComponentProps={{
        tabData: tabData,
        selectData: selectData,
        treeData: Inventorytreeviewdata,
      }}
      data-testid="splitter"
      RightComponent={Home}
      rightComponentProps={rightComponentProps}
    />
  );
}

原测试文件(Dashboard.test.tsx,无法正常工作)

import { screen, render } from '@testing-library/react'
import { DashBoard } from "../dashboard"

import { Inventorytreeviewdata } from '../../../../constants/treeData'

const Splitter = jest.mock('@valgenesis/utility',({Splitter})=>Splitter)
jest.mock('../DashBoard',()=>()=>Splitter)

describe('dashboard renders correctly',()=>{
    test('tests',()=>{
        const {container} = render(<DashBoard/>)
        expect(Splitter).toBeInTheDocument();
    })
})

Splitter.tsx(Utility应用)

import { ChevronLeft, ChevronRight } from "@mui/icons-material";
import { Box, Button, Stack, Typography } from "@mui/material";
import React from "react";
import { SplitterProps } from "./Splitter.type";
import "./Splitter.scss";

function Splitter(props: SplitterProps) {
  const {
    RightComponent,
    rightComponentProps,
    LeftComponent,
    leftComponentProps,
  } = props;

  const [collapse, setCollapse] = React.useState<boolean>(false);

  const handleCollapse = (): void => {
    setCollapse(!collapse);
  };

  return (
    <Stack spacing={0} direction="row" className="templateWrapper" sx={{ height: "calc(100vh - 48px)" }} >
      <Box data-testid="leftWrapper" sx={{ position: "relative", backgroundColor: "#fff", borderRight: "1px solid lightgrey", width: collapse ? "20px" : "335px", height: "100%", transition: "0.3s" }}>
        <Button
          variant="contained"
          className="collapseButton"
          onClick={handleCollapse}
          sx={{
            position: "absolute",
            right: "-12px",
            top: "10px",
            p: 0,
            minWidth: "auto",
            color: "#707070",
            border: "1px solid #707070",
            backgroundColor: "#fff",
            boxShadow: "none"
          }}
        >
          {collapse ? <ChevronRight /> : <ChevronLeft />}
        </Button>

        {!collapse && <LeftComponent {...leftComponentProps} />}
      </Box>
      <Box data-testid="rightWrapper" sx={{ width: "100%", height: "calc(100vh - 48px)" }}>
        <RightComponent {...rightComponentProps} />
      </Box>
    </Stack>
  );
}

export default Splitter;

修复后的测试方案

1. 核心修复思路

针对Dashboard中导入Splitter的真实来源(mycomponent)进行Mock,编写可渲染的Mock组件并验证props传递逻辑,避免错误Mock自身组件。

2. 修正后的Dashboard.test.tsx

import { screen, render } from '@testing-library/react';
import { DashBoard } from "../dashboard";
import { tabData, selectData, Inventorytreeviewdata } from '../../../../constants';
import { rightComponentProps } from '../../../../constants/ComponentProps';

// Mock 来自mycomponent的Splitter、LeftPanel和axios
jest.mock('mycomponent', () => ({
  // Mock Splitter组件,保留props接收逻辑并添加测试标识
  Splitter: jest.fn((props) => (
    <div data-testid="mocked-splitter">
      {props.LeftComponent && <props.LeftComponent {...props.leftComponentProps} />}
    </div>
  )),
  // Mock LeftPanel组件
  LeftPanel: jest.fn(() => <div data-testid="mocked-left-panel" />),
  // Mock axios避免测试干扰
  axios: jest.fn()
}));

describe('Dashboard组件渲染测试', () => {
  test('应正确渲染Splitter组件并传入预期props', () => {
    render(<DashBoard />);

    // 断言Splitter组件已渲染
    expect(screen.getByTestId('mocked-splitter')).toBeInTheDocument();
    // 断言LeftPanel组件已渲染
    expect(screen.getByTestId('mocked-left-panel')).toBeInTheDocument();

    // 验证Splitter接收到的props是否符合预期
    const Splitter = require('mycomponent').Splitter;
    expect(Splitter).toHaveBeenCalledWith(
      expect.objectContaining({
        LeftComponent: expect.any(Function),
        leftComponentProps: {
          tabData,
          selectData,
          treeData: Inventorytreeviewdata
        },
        'data-testid': 'splitter',
        RightComponent: expect.any(Function),
        rightComponentProps
      }),
      expect.anything()
    );
  });
});

关键修复点

  • 修正Mock目标:针对实际导入的mycomponent包Mock,而非错误Mock自身的DashBoard组件
  • 合理编写Mock组件:返回可渲染的React元素,同时保留对传入props的验证能力
  • 正确断言逻辑:通过测试标识(testid)断言组件渲染状态,而非直接断言Mock函数
  • 验证props传递:确保Dashboard向Splitter传递的参数完全符合预期

额外注意事项

  • 若无需验证内部子组件,可简化Splitter的Mock为仅返回带testid的空div
  • 如需测试样式或MUI组件交互,可引入@testing-library/jest-dom扩展增强断言能力

内容的提问来源于stack exchange,提问作者Joel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 18:47:16