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
相关产品推荐
相关产品推荐

