Как протестировать порядок записей в Rails?

#ruby-on-rails #testing

#ruby-on-rails #тестирование

Вопрос:

Я нахожу очень подробным и утомительным проверять, правильно ли упорядочены записи, поступающие из базы данных. Я думаю использовать метод array ‘==’ для сравнения двух массивов поиска. Элементы и порядок массива должны быть одинаковыми, чтобы он казался подходящим. Проблема в том, что если элементы отсутствуют, тест завершится неудачей, даже если они строго упорядочены должным образом.

Интересно, есть ли способ получше…

Ответ №1:

Rails 4

app/models/person.rb

 default_scope { order(name: :asc) }
  

test/models/person.rb

 test "people should be ordered by name" do
  xavier = Person.create(name: 'xavier')
  albert = Person.create(name: 'albert')
  all    = Person.all
  assert_operator all.index(albert), :<, all.index(xavier)
end
  

Rails 3

app/models/person.rb

 default_scope order('name ASC')
  

test/unit/person_test.rb

 test "people should be ordered by name" do 
  xavier = Person.create name: 'xavier'
  albert = Person.create name: 'albert'
  assert Person.all.index(albert) < Person.all.index(xavier)
end
  

Комментарии:

1. Это здорово, но плохо масштабируется с массивами, содержащими много объектов. assert_operator, кстати, доступен с rails 3.

Ответ №2:

Я не сталкивался со встроенным способом сделать это красиво, но вот способ проверить, отсортирован ли массив объектов по элементу:

 class MyObject
  attr_reader :a

  def initialize(value)
    @a = value
  end
end

a = MyObject.new(2)
b = MyObject.new(3)
c = MyObject.new(4)

myobjects = [a, b, c]

class Array
  def sorted_by?(method)
    self.each_cons(2) do |a|
      return false if a[0].send(method) > a[1].send(method)
    end
    true
  end
end

p myobjects.sorted_by?(:a) #=> true
  

Затем вы можете использовать это, используя что-то вроде:

 test "people should be ordered by name by default" do 
  people = Person.all
  assert people.sorted_by?(:age)
end
  

Ответ №3:

Я наткнулся на то, что искал, когда задавал этот вопрос. Используя метод each_cons, это делает тест очень аккуратным:

 assert Person.all.each_cons(2).all?{|i,j| i.name >= j.name}
  

Комментарии:

1. Для следующего пользователя, у которого возникнет соблазн переформатировать это {..} на do..end — не делайте этого. лол

Ответ №4:

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

Таким образом, я думаю, вам не понадобится метод array ==

HTH

sameera

Комментарии:

1. Самира, спасибо за твой ответ, но я спрашиваю, как протестировать сортировку, а не как сортировать.

2. гамов, сначала пройдись по набору записей и получи идентификаторы в массив, затем продублируй тот же массив и отсортируй его (Array.sort) и сравни 2 массива, они должны совпадать один к одному. приветствую sameera