Подтвердить что ты не робот

RSpec: Нулевые цепи с аргументами?

Просто интересно, могут ли/быть аргументы в цепях 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 в условия заглушки?

4b9b3361

Ответ 1

Вы можете использовать это:

Payment.stub_chain(:order, :where).with(:updated_at).with(:paid => true) { return_this }

Ответ 2

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

Я использую 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}]

Ответ 3

С помощью rspec > 3 используйте этот синтаксис:

expect(Converter).to receive_message_chain("new.update_value").with('test').with(no_args)

вместо stub_chain.

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