我的模型有default_scope(:order =>'created_at') 我的测试(rspec,工厂女孩,应该等) 是:
require 'spec/spec_helper.rb'
describe CatMembership do
context "is valid" do
subject { Factory.build(:cat_membership) }
it { should be_valid }
it { should belong_to :cat}
it { should belong_to :cat_group}
it { should have_db_column(:start_date)}
it { should have_db_column(:end_date)}
end
end
答案 0 :(得分:29)
我宁愿使用查询并检查结果进行测试,但如果你真的必须这样做,一个可能的解决方案就是这样的Rails 3:
CatMembership.scoped.to_sql.should == CatMembership.order(:created_at).to_sql
在Rails 2上:
CatMembership.default_scoping.should == [{:create=>{}, :find=>{:order=>"created_at"}}]
但我不会说这些解决方案是理想的,因为它们显示了很多实现知识(你可以看到实现因Rails版本而异)。
创建示例数据,运行通常的所有查询并检查结果是否正确有序可能更简单,更接近真实的单元测试,即使在升级rails版本时也能正常工作。 / p>
在这种情况下,它可能是:
before do
@memberships = []
@memberships << CatMembership.create!
@memberships << CatMembership.create!
@memberships << CatMembership.create!
[ 1.hour.ago, 5.minutes.ago, 1.minute.ago ].each_with_index do |time, index|
membership = @memberships[index]
membership.created_at = time
membership.save
end
end
it 'should be correctly ordered' do
@sorted_memberships = CatMembership.all
@memberships.first.should == @sorted_memberships.last
@memberships.second.should == @sorted_memberships.second
@memberships.third.should == @sorted_memberships.first
end
它更加冗长,但即使你在轨道上向前迈进,它也会起作用。
现在我刚刚注意到谁问了这个问题:D
答案 1 :(得分:3)
最有可能的是,您将拥有多个具有类似默认范围的模型(如果没有,通常会忽略此方法),因此您可以将此Rspec示例放入shared_example,您可以从各种模型中调用它规格。
我首选的检查默认范围的方法是确保默认的ActiveRecord::Relation
具有预期的子句(order
或where
或者不管情况如何),如下所示: / p>
<强>规格/支持/ shared_examples / default_scope_examples.rb 强>
shared_examples_for 'a default scope ordered by created_at' do
it 'adds a clause to order by created_at' do
described_class.scoped.order_clauses.should include("created_at")
end
end
然后在您的CatMembership
规范(以及具有相同默认范围的任何其他规范)中,您只需要:
<强>规格/模型/ cat_membership_spec.rb 强>
describe CatMembership
it_behaves_like 'a default scope ordered by created_at'
# other spec examples #
end
最后,你可以看到这种模式如何扩展到各种默认范围,并保持干净,有条理,最重要的是,DRY。
答案 2 :(得分:0)
根据RSpec
expect
的最新惯例,建议使用should
,而不是expect(CatMembership.scoped.to_sql).to eq(CatMembership.order(:created_at).to_sql)
,所以更好的答案是
Model.scoped
但是,最近{@ 1}}已弃用,因此建议使用Model.all
代替
expect(CatMembership.all.to_sql).to eq(CatMembership.order(:created_at).to_sql)