Rails – Тестирование именованных областей: результаты тестирования или конфигурация области?

Как следует тестировать именованные области Rails? Проверяете ли вы результаты, возвращаемые из области действия, или правильность настройки вашего запроса?

Если у меня есть класс User с методом .admins, например:

class User < ActiveRecord::Base
  def self.admins
    where(admin: true)
  end
end

Я бы, вероятно, указал, чтобы убедиться, что я получаю результаты, которые я ожидаю:

describe '.admins' do
  let(:admin) { create(:user, admin: true) }
  let(:non_admin) { create(:user, admin: false) }
  let(:admins) { User.admins }

  it 'returns admin users' do
    expect(admins).to include(admin)
    expect(admins).to_not include(non_admin)
  end
end

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

Однако в последнее время я видел, что области определяются путем подтверждения их правильной настройки, а не возвращаемого набора результатов. Для этого примера что-то вроде:

describe '.admins' do
  let(:query) { User.admins }
  let(:filter) { query.where_values_hash.symbolize_keys }
  let(:admin_filter) { { admin: true } }

  it 'filters for admin users' do
    expect(filter).to eq(admin_filter) # or some other similar assertion
  end
end

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

Однако меня это беспокоит, потому что:

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

Пример, который я использовал, настолько тривиален, что, возможно, я был бы в порядке, просто протестировав конфигурацию, но:

  • где вы проводите черту и говорите, что «содержание этой именованной области слишком сложно и требует тестов для подтверждения результатов, помимо простого тестирования конфигурации области»? Эта линия вообще существует или должна быть?
  • Существует ли законный/хорошо принятый/"лучшая практика" (извините) способ протестировать именованные области, не касаясь базы данных или, по крайней мере, минимально касаясь ее, или это просто неизбежно?
  • Используете ли вы какой-либо из вышеперечисленных способов проверки своих областей видимости или какой-либо другой метод?

Этот вопрос (вопросы) немного похож на Тестирование именованных областей с помощью RSpec, но мне не удалось найти ответы/ мнения о результатах тестирования по сравнению с конфигурацией области.


person Paul Fioravanti    schedule 07.04.2014    source источник


Ответы (1)


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

Если ваша область применения тривиальна, заурядна where, с некоторыми order и т. д., нет реальной необходимости тестировать ActiveRecord или базу данных, чтобы убедиться, что они работают правильно — вы можете с уверенностью предположить, что они были правильно реализованы, и просто проверьте структуру, которую вы ожидаете.

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

Это также поможет вам, если и когда вы решите изменить стратегию (использовать эту классную новую функцию mysql или перенести на postgresql), безопасно провести рефакторинг, проверив надежность функциональности.

Это гораздо лучший способ, чем просто проверить, что строка SQL - это то, что вы там напечатали...

person Uri Agassi    schedule 07.04.2014
comment
+1 Спасибо за вдумчивый ответ. Просто чтобы уточнить, я намеревался со спецификацией, основанной на результатах, никогда не тестировать сам ActiveRecord, а интерфейс User.admins: мне все равно, что происходит под обложками интерфейса (очевидно, в этом случае, как и во всех обычных областях Rails , он использует ActiveRecord), просто я получаю набор результатов, который включает/исключает пользователей в соответствии с тем, как я определил пользователя-администратора. Я согласен с вами в отношении тестирования результатов по расширенным запросам, но мне интересно, насколько продвинуты продвинутые, когда становится рискованно тестировать только конфигурацию области... - person Paul Fioravanti; 08.04.2014
comment
Я бы сказал, что если вы прибегаете к написанию SQL в своем коде - функциональность ActiveRecord гарантирует только то, что этот SQL будет запущен, конечно, проверки что SQL выполняется, будет недостаточно, и вы бы хотите проверить его результаты. Что касается того, насколько сложной должна быть область видимости (не прибегая к SQL), прежде чем она будет называться расширенной, я думаю, ваша интуиция так же хороша, как и моя, но я думаю, что вы узнаете это, когда увидите... - person Uri Agassi; 08.04.2014
comment
Большое спасибо за ответ, Ури. Похоже, что все в значительной степени с вами согласны, поэтому, пожалуйста, наслаждайтесь своими бонусными интернет-баллами :-) Я оставлю вопрос открытым еще немного на случай, если кто-то опубликует ответ с некоторыми анекдотами о своих собственных процедурах тестирования области и т. д. В противном случае я приму это и закрою вопрос. - person Paul Fioravanti; 17.04.2014