Ответ 1
Вы можете использовать это:
Payment.stub_chain(:order, :where).with(:updated_at).with(:paid => true) { return_this }
Просто интересно, могут ли/быть аргументы в цепях rspec. Чтобы привести пример, предположим, что у меня есть следующее действие:
def index
@payments = Payment.order(:updated_at).where(:paid => true)
@bad_payments = Payment.order(:some_other_field).where(:paid => false)
end
В моей спецификации контроллера я хотел бы иметь возможность вырезать оба метода и возвращать разные результаты. Если в действии было только поле @payments
, я бы использовал что-то вроде
Payment.stub_chain(:order, :where) { return_this }
Но, конечно, это вернет то же значение для @bad_payments
.
Итак - короче говоря, как включить :updated_at
и :paid => true
в условия заглушки?
Вы можете использовать это:
Payment.stub_chain(:order, :where).with(:updated_at).with(:paid => true) { return_this }
Вы можете использовать вложенный блокирующий блок. Блок может принимать аргументы, а возвращаемое значение используется как возвращаемое значение функции.
Я использую tap
, потому что stub
не возвращает вызываемого абонента. mock, созданный double
, возвращается как результат метода order
, метод where
снова закроется.
Payment.stub(:order) { |order|
double('ordered_payments').tap { |proxy|
proxy.stub(:where) { |where|
[order, where]
}
}
}
Payment.order(:updated_at).where(:paid => true)
# => returns [:updated_at, {:paid => true}]
С помощью rspec > 3
используйте этот синтаксис:
expect(Converter).to receive_message_chain("new.update_value").with('test').with(no_args)
вместо stub_chain
.
Подробнее о цепочках сообщений в документации. И здесь - это документация согласования аргументов.