Как я могу сделать тест rspec для моей области по умолчанию - PullRequest
18 голосов
/ 28 июля 2011

у моей модели есть default_scope (: order => 'creation_at') мои тесты (rspec, factory girl, musta и т. Д.):

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

Ответы [ 3 ]

29 голосов
/ 28 июля 2011

Я бы предпочел проверить это с помощью запроса и проверки результатов, но если вам действительно нужно это сделать, одним из возможных решений было бы что-то вроде этого для 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).

Созданиедемонстрационные данные, выполняющие обычный запрос all и проверяющие правильность упорядоченного результата, могли бы быть проще, приблизиться к реальному модульному тестированию и работать даже при обновлении версии 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

3 голосов
/ 19 декабря 2014

DRY It Up, используйте общие примеры

Скорее всего, у вас будет более одной модели с одинаковой областью действия по умолчанию (если нет, в основном игнорируйте этот метод), так что вы можете поместить этот пример 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

Наконец, вы можете увидеть, как этот шаблон можно распространить на все виды областей по умолчанию, чтобы он был чистым, организованным и, что самое главное, СУХИМЫМ.

0 голосов
/ 14 июня 2015

Согласно последним соглашениям 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)

...