RSpec: Stub chains with arguments?

自作多情 提交于 2019-12-18 01:28:34

问题


Just wondering if/how arguments can be passed in rspec stub chains. To give an example, suppose I have the following action:

def index
  @payments = Payment.order(:updated_at).where(:paid => true)
  @bad_payments = Payment.order(:some_other_field).where(:paid => false)
end

In my controller spec, I'd like to be able to stub out both methods and return different results. If only the @payments field were in the action I'd use something like

Payment.stub_chain(:order, :where) { return_this }

But of course, that will return the same value for @bad_payments.

So - in short, how do I include the :updated_at and :paid => true as stub conditions?


回答1:


You can use this:

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



回答2:


With rspec > 3 use this syntax:

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

instead of stub_chain.

Read more about message chains in the documenation. And here is the argument matchers documentation.




回答3:


You can use nested stub block. The block can accept arguments, and the return value is used as function return value.

I use tap because stub does not returns the callee. The mock created by double is returned as the result of method order, which where method is stub again.

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}]


来源:https://stackoverflow.com/questions/8003445/rspec-stub-chains-with-arguments

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!