微前端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
相关产品推荐
相关产品推荐

