Ruby on rails 带参数的Rspec 3 Rails 4模拟链式方法调用

Ruby on rails 带参数的Rspec 3 Rails 4模拟链式方法调用,ruby-on-rails,rspec,mocking,Ruby On Rails,Rspec,Mocking,我试图模仿下面这句话: publishers = AdminUser.where(can_publish: true).pluck(:email) 我试过: relation = instance_double('AdminUser::ActiveRecord_Relation') allow(AdminUser).to receive(:where).with(can_publish: true).and_return(relation) allow(relation).to receive

我试图模仿下面这句话:

publishers = AdminUser.where(can_publish: true).pluck(:email)
我试过:

relation = instance_double('AdminUser::ActiveRecord_Relation')
allow(AdminUser).to receive(:where).with(can_publish: true).and_return(relation)
allow(relation).to receive(:pluck).with(:email).and_return(['email', 'email2'])
不幸的是,这种期望似乎并不相符。不会抛出错误,但不会模拟方法

我也试过让弹拨发挥作用

  allow(AdminUser).to receive(:where).with(can_publish: true).and_return([object, object2])
但是,当它与另一个
where
调用代码中的较高值相匹配时,该期望值太高,并且失败


如何模拟这一行?

尽管您可以按照建议使用
接收消息链
,但将这种复杂性的需要视为您的类接口可能更干净的指示

考虑使用任何一个接收消息的代码链。< /P>


更好的方法是在
AdminUser
上定义一个名为
publisher\u emails
的类方法,这将更易于存根,并提高代码的可读性。

您可以在双精度上存根方法调用:

require 'rails_helper'

RSpec.describe AdminUser, type: :model do
  let(:expected) { ["a@example.com"] }
  let(:relation) { double(pluck: expected) }

  it "returns the expected value" do
    allow(AdminUser).to receive(:where).with(can_publish: true).and_return(relation)
    publishers = AdminUser.where(can_publish: true).pluck(:email)
    expect(publishers).to eq expected
  end
end

这是一个很好的观点,我可能会根据需要重构代码。然而,在这一点上,我更好奇的是,我们如何能够嘲笑这一行。