RSpec:带参数的存根链?

33

只是想知道如何在rspec stub链中传递参数。举个例子,假设我有以下的操作:

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包含在存根条件中呢?


如果有帮助的话,请查看这个答案 - Arup Rakshit
3个回答

23

您可以使用这个:

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

7
这似乎并不起作用。好像 with 参数被忽略了。尝试将其更改为应该失败的内容,但测试仍然会通过。 - Zubin
@Zubin是正确的,我尝试将with更改为任意值,没有抛出错误,这意味着with调用被忽略了。 - Maximiliano Guzman
在新的rspec版本中,此功能已被弃用。 - VPaul

17

使用 rspec > 3 时,请使用以下语法:

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

使用 stub_chain 的替代方法。

关于消息链的更多信息,请阅读文档。并且这里是参数匹配器的文档。


4
似乎这个不起作用。第一次调用 with 被忽略了。 - Anthony To
是的,我也遇到了同样的问题。第一个with()方法中的args没有被测试。你们找到任何解决方案了吗? - Ramyani
在提到的文档中,关于 receive_message_chain 没有提及 with - Sebastián Palma
这应该是被接受的解决方案,因为当前被接受的解决方案在新的rspec版本中已过时。 - VPaul

16
您可以使用嵌套存根块。该块可以接受参数,并且返回值用作函数的返回值。 我使用了tap,因为stub不会返回被调用方。由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}]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接