如何Mock MUI组件内的handleChange及WebSocket调用以通过测试
解决MUI FilterCheckbox组件测试的WebSocket报错问题
针对你遇到的测试环境无服务端导致WebSocket连接失败、进而测试断言失败的问题,这里提供两种可行的解决方案:
方案一:Mock全局WebSocket对象(推荐)
直接模拟WebSocket的行为,避免真实连接,同时还能验证消息发送逻辑,适配函数组件和类组件。
步骤:
- 在测试文件顶部mock全局的WebSocket构造函数,返回一个处于
OPEN状态的模拟对象,规避CONNECTING状态报错:
global.WebSocket = jest.fn(() => ({ send: jest.fn(), // 模拟send方法,用于后续验证消息发送逻辑 readyState: 1, // 1代表OPEN状态,跳过真实连接流程 close: jest.fn(), // 模拟close方法,避免内存泄漏 }));
- 编写测试用例,触发复选框点击,验证状态切换和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
相关产品推荐
相关产品推荐

