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

Sequel框架下如何Mock多Join查询?技术求助

解决Sequel多Join操作的Rspec Mock问题

首先得明确:Sequel的join是链式调用,每次调用join都会返回一个新的Dataset对象,而不是在同一个Office类上连续调用两次join。你当前的写法错误地假设了Office会直接接收两次join调用,这和Sequel的实际工作方式不符。

下面是正确的Mock思路和代码:

正确的Mock步骤

我们需要模拟两次链式的join调用,以及最后的pluck调用:

  • 先Mock第一次join(:address...),让它返回一个模拟的Dataset对象
  • 再Mock这个模拟Dataset对象的join(:office_someone...),返回另一个模拟Dataset对象
  • 最后Mock第二个模拟Dataset的pluck方法,返回你期望的结果

具体代码实现

RSpec.describe "Your test context" do
  it "mocks the chained Sequel joins and pluck" do
    # 模拟第二次join后的数据集,它会响应pluck方法
    someone_join_dataset = double("SomeoneJoinDataset")
    expect(someone_join_dataset).to receive(:pluck).with(:someone_id).and_return([1])

    # 模拟第一次join后的数据集,它会响应第二次join调用并返回上面的数据集
    address_join_dataset = double("AddressJoinDataset")
    expect(address_join_dataset).to receive(:join).with(:office_someone, id: :id).and_return(someone_join_dataset)

    # 让Office类响应第一次join调用,返回第一次join后的模拟数据集
    expect(Office).to receive(:join).with(:address, id: :address_id).and_return(address_join_dataset)

    # 执行你的代码并断言结果
    result = Office.join(:address, id: :address_id).join(:office_someone, id: :id).pluck(:someone_id)
    expect(result).to eq([1])
  end
end

额外说明

  • 如果你的代码里还用到了其他Dataset方法(比如where、order等),只需要在对应的模拟Dataset对象上添加对应的expect即可
  • 如果你不想手动创建多个double,也可以使用RSpec的stub_chain方法来简化链式调用的Mock,但显式创建double的方式更清晰,便于调试

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:50:12