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

React快照测试中如何Mock react-bootstrap组件?

问题:React-Bootstrap Modal包裹的组件快照测试返回null

我在开发一个用React-Bootstrap做UI的React项目,用Jest做快照测试。当组件被Bootstrap Modal包裹时,生成的快照始终是null;去掉Modal直接返回表单的话,快照就正常。我想Mock Bootstrap Modal,只返回一个简单实现,不影响库的其他部分,减少传递React-Bootstrap各类Props的复杂度。

组件代码

function MyComponent(){
  return (
    <div>
      <Modal
        show={props.showReviewModal}
        onHide={handleClose}
        className="well-connection-review"
      >
        <Modal.Header closeButton>
          <Modal.Title className="m-auto p-auto">
            Modal Title
          </Modal.Title>
        </Modal.Header>
        <Form
          noValidate
          validated={validated}
          onSubmit={(e) => handleValidation(e)}
        >
          <Modal.Body>
            <Form.Row className="m-2 d-flex align-items-center">
              <Form.Group as={Col} controlId="formPowerCompany" className="m-1">
                <Form.Label className="label">Power Company</Form.Label>
                <Select
                  isClearable={true}
                  name="PowerCompany"
                  options={ELECTRIC_PROVIDERS}
                  className="basic-multi-select well-connection-report-filters"
                  onChange={PowerCompanyChange}
                  value={powerCompany}
                  isSearchable={false}
                  placeholder="Power Company"
                />
              </Form.Group>
            </Form.Row>
            <Form.Row className="m-2 d-flex align-items-center">
              <Form.Group as={Col} controlId="formMeterID" className="m-1">
                <Form.Label className="label">Meter ID</Form.Label>
                <Form.Control
                  type="text"
                  value={meterId}
                  name="meterId"
                  onChange={handleChange}
                  autoComplete="off"
                />
                <Form.Control.Feedback type="invalid">
                  Please enter an ID
                </Form.Control.Feedback>
              </Form.Group>
            </Form.Row>
          </Modal.Body>

          <Modal.Footer className="mr-3">
            <Button
              variant="primary"
              onClick={() => handleClose()}
              type="submit"
            >
              Close
            </Button>
          </Modal.Footer>
        </Form>
      </Modal>
    </div>
  );
}

export default MyComponent;

测试用例代码

import React from "react";
import MyComponent from "../MyComponent";
import renderer from "react-test-renderer";

describe("Snapshot testing of MyComponent", () => {
    it("MyComponent snapshot", () => {
        const MyComponent = renderer.
        create(<MyComponent message={"message"} />).toJSON();
        expect(MyComponent).toMatchSnapshot();
    });
});

快照输出结果

// Jest Snapshot v1, [link to jest docs]

exports[`Snapshot testing of MyComponent`] = `null`;

解决方案

原因分析

React-Bootstrap的Modal组件在show属性为false时,会直接渲染null。你的测试用例里没有传递showReviewModal props,组件内Modal的show值默认是false,导致整个组件快照为null。

方法1:传递Props让Modal显示

直接给测试组件传入showReviewModal={true},让Modal正常渲染:

import React from "react";
import MyComponent from "../MyComponent";
import renderer from "react-test-renderer";

describe("Snapshot testing of MyComponent", () => {
    it("MyComponent snapshot", () => {
        const component = renderer.create(
            <MyComponent message={"message"} showReviewModal={true} />
        ).toJSON();
        expect(component).toMatchSnapshot();
    });
});

方法2:Mock React-Bootstrap的Modal组件(推荐)

如果不想依赖Modal内部逻辑,可通过Jest Mock掉Modal,让它直接渲染子元素,同时保留React-Bootstrap其他组件的原实现:

步骤1:创建Mock文件

在项目根目录新建__mocks__文件夹,然后创建react-bootstrap.js文件:

// __mocks__/react-bootstrap.js
import React from 'react';
import * as ReactBootstrap from 'react-bootstrap';

// 自定义Modal的Mock实现
const MockModal = ({ children, ...props }) => (
  <div data-testid="mock-modal" {...props}>
    {children}
  </div>
);

MockModal.Header = ({ children, ...props }) => (
  <div data-testid="mock-modal-header" {...props}>
    {children}
  </div>
);

MockModal.Title = ({ children, ...props }) => (
  <div data-testid="mock-modal-title" {...props}>
    {children}
  </div>
);

MockModal.Body = ({ children, ...props }) => (
  <div data-testid="mock-modal-body" {...props}>
    {children}
  </div>
);

MockModal.Footer = ({ children, ...props }) => (
  <div data-testid="mock-modal-footer" {...props}>
    {children}
  </div>
);

// 导出时保留其他组件的原实现,仅替换Modal
export default {
  ...ReactBootstrap,
  Modal: MockModal,
};

步骤2:在测试中启用Mock

修改测试用例,让Jest使用自定义的Mock:

import React from "react";
import MyComponent from "../MyComponent";
import renderer from "react-test-renderer";

// 启用react-bootstrap的Mock
jest.mock('react-bootstrap');

describe("Snapshot testing of MyComponent", () => {
    it("MyComponent snapshot", () => {
        const component = renderer.create(
            <MyComponent message={"message"} />
        ).toJSON();
        expect(component).toMatchSnapshot();
    });
});

这样Mock后,Modal会渲染为简单的div容器,无论show属性是什么,都会正常渲染子元素,快照就能生成完整内容,同时Form、Button等其他React-Bootstrap组件不受影响。

内容的提问来源于stack exchange,提问作者Salvino D'sa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 23:51:36