Сложные запросы Arel и заглушки RSpec

Допустим, у нас есть такой фрагмент кода:

def index
  @posts = Post.where(:status => ACTIVE)
  if params[:s]
    @posts = Post.where("title like ?", "%#{params[:s]}%").order("title asc")
  else
    @posts = Post.limit(20).order("date desc")
  end
end

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

Как лучше всего заглушить сложный запрос Arel для RSpec, если вы не знаете порядок или количество вызовов методов?

ПРИМЕЧАНИЕ. Я просматривал заглушки связанных запросов в Rails 3 и Rspec и я думаю, что хочу что-то вроде stub_chain_with_indifferent_order(:where, :order, :limit).


person Kostas    schedule 01.08.2011    source источник
comment
Если вы действительно хотите специфицировать запросы, их заглушка обычно является неправильным ответом. Вы хотите проверить поведение, а не параметры, которые вы задали методу. Загрузите данные в базу данных и запустите запрос к данным, а затем проверьте, действительно ли он соответствует вашим критериям.   -  person Maurício Linhares    schedule 01.08.2011
comment
То, что я пытаюсь сделать, это проверить такие вещи, как должно быть назначено @posts или отображать один li на сообщение в @posts, где заглушка действительно полезна, чтобы избежать накладных расходов db.   -  person Kostas    schedule 01.08.2011


Ответы (1)


Это может быть код, говорящий вам, что вы делаете это на неправильном уровне. Это то, что мне действительно нравится в философии RSpec MOCK ALL THE THINGS(!!): если становится трудно имитировать, возможно, ваш дизайн неверен.

Например, я мог бы реорганизовать ваш код так:

def index
  @posts = Post.posts_for(:like => params[:s], :order => (params[:s] ? "title asc" : "date desc")
end

(Или что-то лучше, учитывая ваш домен.)

Затем вы можете имитировать Posts.posts_for, простой вызов метода, вместо того, чтобы пытаться имитировать тонну цепочек методов AR.

person RyanWilcox    schedule 15.08.2011
comment
Мне нравится, к чему вы пришли, но я чувствую себя немного некомфортно, создавая универсальный метод. Вся идея arel (которую я не собираюсь защищать или осуждать, это просто DSL, который мне вручили) заключается в том, что вы управляете запросами через инкрементные единицы поведения, артикулированные вызовами методов. При этом я соглашусь, что мой код кажется довольно вонючим и теряет часть языка предметной области проблемы, которую пытается решить мое приложение. - person Steve Y; 02.08.2012