18

我的模型有 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
4

3 回答 3

30

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

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

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

于 2011-07-28T03:54:01.177 回答
3

干掉它,使用共享示例

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

我检查默认范围的首选方法是确保默认ActiveRecord::Relation具有预期的子句(orderwhere任何情况),如下所示:

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

于 2014-12-19T19:17:12.457 回答
0

根据RSpec expect推荐的最新约定而不是should这样,更好的答案是

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

但是,最近Model.scoped已弃用,因此建议Model.all改用

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

于 2015-06-14T12:50:01.173 回答