我如何对我的默认范围进行rspec测试

我的模型有default_scope(:order =>’created_at’)我的测试(rspec,factory girl,shoulda等)是:

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 

我宁愿使用查询并检查结果进行测试,但如果你真的必须这样做,一个可能的解决方案就是这样的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版本而异)。

创建样本数据,运行通常的所有查询并检查结果是否正确有序可能更简单,更接近真实的unit testing,即使在升级rails版本时也能正常工作。

在这种情况下,它可能是:

 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

干涸,使用共享示例

最有可能的是,您将拥有多个具有类似默认范围的模型(如果没有,通常会忽略此方法),因此您可以将此Rspec示例放入shared_example,您可以从各种模型规范中调用它。

我首选的检查默认范围的方法是确保默认的ActiveRecord::Relation具有期望的子句( order或者where或者不管情况如何),如下所示:

规格/支持/ 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。

根据RSpec最新惯例,建议不要这样,更好的答案

expect(CatMembership.scoped.to_sql).to eq(CatMembership.order(:created_at).to_sql)

但是,最近不推荐使用Model.all因此建议使用Model.all

expect(CatMembership.all.to_sql).to eq(CatMembership.order(:created_at).to_sql)