Подтвердить что ты не робот

Как проверить область действия в Rails 3

Какой лучший способ проверить области в Rails 3. В rails 2 я бы сделал что-то вроде:

Rspec:

it 'should have a top_level scope' do
  Category.top_level.proxy_options.should == {:conditions => {:parent_id => nil}}
end

Это не работает в rails 3 с методом undefined `proxy_options 'для ошибки []: ActiveRecord:: Relation.

Как люди проверяют, что область задана с правильными параметрами? Я вижу, вы могли бы изучить объект isl и могли бы сделать некоторые надежды на это, но я не уверен, что лучший способ сделать это будет.

4b9b3361

Ответ 1

Оставив в стороне вопрос о том, как "откликнуться"... здесь, как достичь аналогичного материала в Rails3...

В Rails3 с именами областей разные, поскольку они просто генерируют реляционные операторы Arel. Но, исследуйте!

Если вы перейдете на консоль и введите:

# All the guts of arel!
Category.top_level.arel.inspect

Вы увидите внутренние части Ареля. Он использовал для создания отношения, но также может быть интродуцирован для текущего состояния. Вы увидите общедоступные методы, такие как #where_clauses и т.д.

Тем не менее, сама область обладает множеством полезных общедоступных методов самоанализа, которые упрощают ее, чем прямой доступ к @arel:

# Basic stuff:
=> [:table, :primary_key, :to_sql]

# and these to check-out all parts of your relation:
=> [:includes_values, :eager_load_values, :preload_values,
    :select_values, :group_values, :order_values, :reorder_flag,
    :joins_values, :where_values, :having_values, :limit_value,
    :offset_value, :readonly_value, :create_with_value, :from_value]

# With 'where_values' you can see the whole tree of conditions:
Category.top_level.where_values.first.methods - Object.new.methods
=> [:operator, :operand1, :operand2, :left, :left=, 
    :right, :right=, :not, :or, :and, :to_sql, :each]

# You can see each condition to_sql
Category.top_level.where_values.map(&:to_sql)
=> ["`categories`.`parent_id` IS NULL"]

# More to the point, use #where_values_hash to see rails2-like :conditions hash:
Category.top_level.where_values_hash
=> {"parent_id"=>nil}

Используйте этот последний: #where_values_hash, чтобы проверить области видимости аналогично #proxy_options в Rails2....

Ответ 2

В идеале ваши модульные тесты должны рассматривать модели (классы) и их экземпляры как черные ящики. В конце концов, это не настоящая реализация, о которой вы заботитесь, а о поведении интерфейса.

Поэтому вместо проверки того, что область применения реализована определенным образом (т.е. с определенным набором условий), попробуйте проверить, что она ведет себя правильно, - что она возвращает экземпляры, которые она должна, и не возвращает экземпляры, которые она не должна.

describe Category do
  describe ".top_level" do
    it "should return root categories" do
      frameworks = Category.create(:name => "Frameworks")

      Category.top_level.should include(frameworks)
    end

    it "should not return child categories" do
      frameworks = Category.create(:name => "Frameworks")
      rails = Category.create(:name => "Ruby on Rails", :parent => frameworks)

      Category.top_level.should_not include(rails)
    end
  end
end

Если вы пишете свои тесты таким образом, вы сможете свободно перефазировать свои реализации, как вам будет угодно, без необходимости изменять свои тесты или, что более важно, без необходимости беспокоиться о бессознательном нарушении вашего приложения.

Ответ 3

Вот как я их проверяю. Подумайте об этом:

  scope :item_type, lambda { |item_type|
    where("game_items.item_type = ?", item_type )
  } 

который получает все элементы game_items, где item_type равно значению (например, "Оружие" ):

    it "should get a list of all possible game weapons if called like GameItem.item_type('Weapon'), with no arguments" do
        Factory(:game_item, :item_type => 'Weapon')
        Factory(:game_item, :item_type => 'Gloves')
        weapons = GameItem.item_type('Weapon')
        weapons.each { |weapon| weapon.item_type.should == 'Weapon' }
    end

Я проверяю, что в массиве оружия хранятся только элементы Item_types оружия, а не что-то другое, как перчатки, указанные в спецификации.

Ответ 4

Не знаю, помогает ли это или нет, но я ищу решение и столкнулся с этим вопросом.

Я только что сделал это, и он работает для меня

it { User.nickname('hello').should == User.where(:nickname => 'hello') }

Ответ 5

FWIW, я согласен с вашим оригинальным методом (Rails 2). Создание моделей, предназначенных только для их тестирования, заставляет ваши тесты слишком медленными для непрерывного тестирования, поэтому необходим другой подход. Loving Rails 3, но определенно отсутствует удобство proxy_options!

Ответ 6

Быстро проверить положения области

Я согласен с другими здесь в том, что тестирование фактических результатов, которые вы получаете назад, и обеспечение того, что они ожидаются, на сегодняшний день является лучшим способом, но простая проверка для обеспечения того, чтобы область добавления правильного предложения также может быть полезна для более быстрых тестов, которые не попадают в базу данных.

Вы можете использовать where_values_hash для тестирования условий where. Вот пример использования Rspec:

it 'should have a top_level scope' do
  Category.top_level.where_values_hash.should eq {"parent_id" => nil}
end

Несмотря на то, что документация очень тонкая и иногда несуществующая, существуют аналогичные методы для других типов условий, например:

order_values ​​

Category.order(:id).order_values
# => [:id]

select_values ​​

Category.select(:id).select_values
# => [:id]

group_values ​​

Category.group(:id).group_values
# => [:id]

having_values ​​

Category.having(:id).having_values
# => [:id]

и т.д..

Масштаб по умолчанию

Для областей по умолчанию вы должны обрабатывать их несколько иначе. Отметьте этот ответ для лучшего объяснения.