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

如何Mock MUI组件内的handleChange及WebSocket调用以通过测试

解决MUI FilterCheckbox组件测试的WebSocket报错问题

针对你遇到的测试环境无服务端导致WebSocket连接失败、进而测试断言失败的问题,这里提供两种可行的解决方案:

方案一:Mock全局WebSocket对象(推荐)

直接模拟WebSocket的行为,避免真实连接,同时还能验证消息发送逻辑,适配函数组件和类组件。

步骤:

  1. 在测试文件顶部mock全局的WebSocket构造函数,返回一个处于OPEN状态的模拟对象,规避CONNECTING状态报错:
global.WebSocket = jest.fn(() => ({
  send: jest.fn(), // 模拟send方法,用于后续验证消息发送逻辑
  readyState: 1, // 1代表OPEN状态,跳过真实连接流程
  close: jest.fn(), // 模拟close方法,避免内存泄漏
}));
  1. 编写测试用例,触发复选框点击,验证状态切换和WebSocket消息发送:
import { render, screen, fireEvent } from '@testing-library/react';
import FilterCheckbox from './FilterCheckbox';

describe('FilterCheckbox', () => {
  // 每次测试前清除mock调用记录,避免用例间干扰
  beforeEach(() => {
    jest.clearAllMocks();
  });

  it('切换复选框状态并正确发送WebSocket消息', () => {
    render(<FilterCheckbox label="测试过滤器" />);
    const checkbox = screen.getByLabelText('测试过滤器');

    // 验证初始状态未选中
    expect(checkbox).not.toBeChecked();

    // 点击复选框
    fireEvent.click(checkbox);
    // 验证状态变为选中
    expect(checkbox).toBeChecked();
    // 验证WebSocket的send方法被调用,且参数符合预期
    const mockSocket = global.WebSocket.mock.instances[0];
    expect(mockSocket.send).toHaveBeenCalledWith(JSON.stringify({ checked: true }));

    // 再次点击,验证状态切换和消息发送逻辑
    fireEvent.click(checkbox);
    expect(checkbox).not.toBeChecked();
    expect(mockSocket.send).toHaveBeenCalledWith(JSON.stringify({ checked: false }));
  });
});

方案二:Mock组件内部的handleChange函数(仅适用于类组件)

如果你的组件是类组件,可以通过jest.spyOn获取组件实例的handleChange方法,替换其实现逻辑,跳过WebSocket发送部分:

测试用例示例:

import { render, screen, fireEvent } from '@testing-library/react';
import FilterCheckbox from './FilterCheckbox';

describe('FilterCheckbox', () => {
  it('点击切换复选框状态', () => {
    const { container } = render(<FilterCheckbox label="测试过滤器" />);
    const checkboxInstance = container.firstChild.instance;
    
    // Spy并改写handleChange方法,只保留状态更新逻辑
    const mockHandleChange = jest.spyOn(checkboxInstance, 'handleChange');
    mockHandleChange.mockImplementation(function(e) {
      this.setState({ checked: e.target.checked });
    });

    const checkbox = screen.getByLabelText('测试过滤器');
    expect(checkbox).not.toBeChecked();

    fireEvent.click(checkbox);
    expect(checkbox).toBeChecked();
    expect(mockHandleChange).toHaveBeenCalled();
  });
});

注意:函数组件的内部函数无法直接通过实例获取,因此这种方法仅适用于类组件,更通用的解决方案是方案一。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 18:22:46