RSpec например переменная в индексе


Это очень простой вопрос, но я не могу найти для него никакого решения. Прошло уже 3 дня. Пожалуйста помочь.

Итак, у меня есть это в

Users_controller.rb

def index
  @users = @users.normal.order(:name).page params[:page]
end

Так что у меня есть это в моем users_controller_spec.rb

it "assign all normal users to @users" do
  users = User.normal.all
  get :index
  expect(assigns(:users)).to eq(users)
end

Мой код основан на https://www.relishapp.com/rspec/rspec-rails/docs/controller-specs .

После запуска rspec в моем терминале, это выход.

  Diff:
   @@ -1,4 +1,4 @@
   -[#<User:0x00000004aa32b0
   +[#<User:0x00000004a085a8
      id: 2,
      name: "Christian Galamay",
      admin: false,
   @@ -20,7 +20,7 @@
      updated_at: Wed, 13 Apr 2016 01:46:17 UTC +00:00,
      role: "Normal",
      avatar: nil>,
   - #<User:0x00000004aa2ea0
   + #<User:0x000000049dbd78
      id: 3,
      name: "Grace Sojor",
      admin: false,
   @@ -42,7 +42,7 @@
      updated_at: Wed, 13 Apr 2016 01:46:17 UTC +00:00,
      role: "Normal",
      avatar: nil>,
   - #<User:0x00000004aa2ab8
   + #<User:0x000000049db760
      id: 4,
      name: "Karl Pandacan",
      admin: false,

Вывод говорит, что все значения одинаковы, за исключением шестигранные после того, как пользователь. Таким образом, мой вопрос (1), Почему шестнадцатеричный после пользователя включен в сравнение двух ActiveRecord (2), есть ли какой-либо метод или функция, чтобы использовать, чтобы игнорировать шестнадцатеричный в пользователе. Спасибо

3 3

3 ответа:

Результат слегка вводит в заблуждение. 2 вещи не равны, потому что они являются объектами отношений, и == между двумя объектами ActiveRecord::Relation работает путем сравнения сгенерированного sql. В вашем случае отношения не равны: в контроллере вы разбиваете страницы и устанавливаете порядок.

Rspec пытается быть полезным, показывая различие вывода to_s 2 объектов, однако это заканчивается сравнением результата запроса (которые действительно являются теми же объектами), и поэтому единственное различие это находки в этой строке вывода являются идентификаторами объектов. Это отчасти удача - без предложения order объекты могли бы быть возвращены в другом порядке. Чтобы быть явным: вывод diff показан только для того, чтобы помочь вам, это не означает, что именно так rspec сделал сравнение.

Если вы хотите сравнить результаты запроса, то вы можете использовать to_a для этого:

 expect(assigns(:users)).to eq(users.to_a)

Если вы не заботитесь о порядке, вы также можете сделать

expect(assigns(:users)).to match_array(users)

Это немного другой тест: он не потерпит неудачу, если БД решит вернуть результаты в другом, что возможно, как я уже упоминал выше.

Вы можете просто проверить массив пользователей вместо активного отношения записи

expect(assigns(:users).to_a).to eq(users.to_a)

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

Попробуйте сравнить значения вашей коллекции с помощью as_json:
expect(assigns(:users).as_json).to eq(users.as_json)