RSpec: цепочки-заглушки с аргументами? - PullRequest
31 голосов
/ 04 ноября 2011

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

Ответы [ 3 ]

23 голосов
/ 10 октября 2013

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

Payment.stub_chain(:order, :where).with(:updated_at).with(:paid => true) { return_this }
16 голосов
/ 23 марта 2016

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

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

вместо stub_chain.

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

15 голосов
/ 15 декабря 2011

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

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