Ruby on rails 如何测试是否对ActiveRecord::Relation的每个元素调用了方法? 问题
我有一个函数,它通过一个关系进行排序,并对每个成员调用一个方法:Ruby on rails 如何测试是否对ActiveRecord::Relation的每个元素调用了方法? 问题,ruby-on-rails,activerecord,rspec,relation,Ruby On Rails,Activerecord,Rspec,Relation,我有一个函数,它通过一个关系进行排序,并对每个成员调用一个方法: def do_stuff count = 0 foo.bars.active.each do |bar| bar.stuff count += 1 end count end 注意:active是bar上返回关系而不是数组的范围 我的测试是这样的: describe :do_stuff do let(:foo) { FactoryGirl.create(:foo) } before
def do_stuff
count = 0
foo.bars.active.each do |bar|
bar.stuff
count += 1
end
count
end
注意:active
是bar
上返回关系而不是数组的范围
我的测试是这样的:
describe :do_stuff do
let(:foo) { FactoryGirl.create(:foo) }
before { foo.bars << FactoryGirl.create(:bar, :mock_stuff) }
subject { foo }
it { subject.do_stuff.should == 1 }
it "does lots of stuff" do
5.times { subject.bars << FactoryGirl.create(:bar, :mock_stuff) }
subject.do_stuff.should == 6
end
end
before do
foo.bars.each do |bar|
bar.should_receive(:stuff)
end
end
let(:foo) { FactoryGirl.create(:foo) }
let(:bar) { double }
let(:array) { [bar] }
before do
foo.stub(:bars).and_return(array)
end
it 'calls stuff on bar' do
expect(bar).to receive(:stuff).once
foo.do_stuff
end
问题是我没有真正验证是否调用过bar.stuff
。当我试图将do_stuf
重构为以下内容时,我伤了自己:
def do_stuff
foo.bars.active.count do |bar|
bar.stuff
end
end
尽管对ActiveRecord::Relation调用count
不会执行块,但所有测试仍然通过:(我希望在我的规范中有一个before
块,它可以执行以下操作:
describe :do_stuff do
let(:foo) { FactoryGirl.create(:foo) }
before { foo.bars << FactoryGirl.create(:bar, :mock_stuff) }
subject { foo }
it { subject.do_stuff.should == 1 }
it "does lots of stuff" do
5.times { subject.bars << FactoryGirl.create(:bar, :mock_stuff) }
subject.do_stuff.should == 6
end
end
before do
foo.bars.each do |bar|
bar.should_receive(:stuff)
end
end
let(:foo) { FactoryGirl.create(:foo) }
let(:bar) { double }
let(:array) { [bar] }
before do
foo.stub(:bars).and_return(array)
end
it 'calls stuff on bar' do
expect(bar).to receive(:stuff).once
foo.do_stuff
end
问题是上面返回的条
与代码中实例化的实例不同
答复
我终于找到了答案。这是一个本该失败的规范,它不会让你担心你是否在迭代数组或关系:
describe :do_stuff do
subject { FactoryGirl.create(:foo, :with_bar) }
it "does stuff to bar" do
Bar.any_instance.should_receive(:stuff)
subject.do_stuff
end
end
这里的技巧是,不能像我在第一个示例中那样在let
块中定义foo
富工厂:
FactoryGirl.define do
data { random_string }
trait :with_bar do
after_build do |foo|
foo.bars << FactoryGirl.create(:bar)
end
end
end
FactoryGirl.define do
数据{random_string}
特点:用_-bar做
建完后做|福|
foo.bar我会这样做:
describe :do_stuff do
let(:foo) { FactoryGirl.create(:foo) }
before { foo.bars << FactoryGirl.create(:bar, :mock_stuff) }
subject { foo }
it { subject.do_stuff.should == 1 }
it "does lots of stuff" do
5.times { subject.bars << FactoryGirl.create(:bar, :mock_stuff) }
subject.do_stuff.should == 6
end
end
before do
foo.bars.each do |bar|
bar.should_receive(:stuff)
end
end
let(:foo) { FactoryGirl.create(:foo) }
let(:bar) { double }
let(:array) { [bar] }
before do
foo.stub(:bars).and_return(array)
end
it 'calls stuff on bar' do
expect(bar).to receive(:stuff).once
foo.do_stuff
end
实际上,您不需要确保它将被调用foo.bar.count
次,我们可以假设rubycount
方法工作正常。如果调用一次,它也将被调用n
次。此解决方案的问题是bar
将返回一个关系而不是一个数组。因此,通过stubing条形图
并返回数组
您已经创建了一个即使代码被破坏也会通过的规范。我知道这一点,因为我做了同样的事情;)刚刚意识到我的问题与我正在处理的代码不匹配。在酒吧里应该有一个范围。很抱歉给你带来了困惑。我将更新这个问题。这并不重要,您可以stub\u chain(:bar,:active)
返回数组。最后,您将得到一个元素迭代器。对关系调用count
意味着它将使用选择count*…
命中数据库并返回一个整数。块内的代码永远不会执行。对数组调用count
将在元素上迭代,因此将执行块。我真的需要类似于Bar.any\u实例的东西。应该接收(:stuff)
但它在我的设置中不起作用。