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

如何在Rails 5.1 + Minitest单元测试中注入Mock对象?

在Rails 5.1 + Minitest中Mock WebSocket连接的解决方案

我来帮你解决这个测试中mock WebSocket连接的问题,核心思路就是拦截WebSocket::Client::Simple.connect这个类方法,让它返回我们预先定义的mock对象,避免实际建立网络连接。下面是具体的实现方案:

1. 构建Mock WebSocket对象

首先创建一个mock实例,模拟你需要的WebSocket行为(比如事件绑定、回调触发等),用Minitest自带的Minitest::Mock就足够了:

mock_websocket = Minitest::Mock.new
# 模拟open事件的绑定,并且可以主动触发回调(如果你的connect方法依赖open事件逻辑)
mock_websocket.expect :on, nil, [:open] do |event, &block|
  block.call if event == :open
end
# 如果你还需要模拟close、message等事件,继续添加expect
mock_websocket.expect :on, nil, [:close]
mock_websocket.expect :on, nil, [:message]

2. 拦截connect方法并返回Mock

使用Minitest的stub方法,临时替换WebSocket::Client::Simple.connect的行为,在代码块内部这个方法会直接返回我们的mock:

test "connect with open" do
  # 先创建mock对象
  mock_websocket = Minitest::Mock.new
  mock_websocket.expect :on, nil, [:open] do |event, &block|
    block.call if event == :open
  end

  # 用stub包裹测试逻辑
  WebSocket::Client::Simple.stub :connect, mock_websocket do
    my_worker = my_workers(:one)
    my_worker.connect # 调用目标方法

    # 断言@websocket被正确赋值为mock对象
    assert_equal mock_websocket, my_worker.instance_variable_get(:@websocket)
    # 验证mock上的所有期望都被触发
    mock_websocket.verify
  end
end

关键细节说明

  • Stub作用域:stub的效果只在代码块内部生效,出了块之后connect方法会恢复原行为,不会干扰其他测试用例。
  • Mock验证:调用mock_websocket.verify可以确保我们定义的所有expect(比如on(:open))都被实际调用过,保证测试的严谨性。
  • 访问实例变量:如果你的Proxy类没有给@websocket提供公开的访问器(比如attr_reader),可以用instance_variable_get(:@websocket)来检查它的值。

如果你的connect方法还有其他对WebSocket的操作,只需要在mock对象上添加对应的expect即可,比如模拟发送消息的方法:

mock_websocket.expect :send, nil, ["test message"]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:13:55