【问题标题】:How to mock message chaining with RSpec?如何使用 RSpec 模拟消息链?
【发布时间】:2016-06-07 15:47:41
【问题描述】:
在我想测试的方法中有一个类似Model.some_scope.pluck(:a_field) 的语句。
对于我来说,用 rspec-mocks 3.4.0 存根这个链式方法调用语句的返回值的推荐方法是什么?我看到 stub_chain 和 receive_message_chain 在 RSpec 网站上都被列为旧语法。
最好的问候。
【问题讨论】:
标签:
ruby-on-rails
ruby
testing
rspec
rspec-mocks
【解决方案1】:
测试该代码的最简洁方法是提取一个方法,例如
class Model < ActiveRecord::Base
def self.some_scope_fields
some_scope.pluck(:a_field)
end
end
该方法可以在没有链的情况下被存根。
但是,有时这样做既不方便也不习惯。例如,在 ActiveRecord 模型的关联方法上调用 create 是惯用的,而不是违反 Demeter 法则。在这些情况下,
如果您不关心方法参数,请使用receive_message_chain。 stub_chain 已弃用; receive_message_chain 不是。 the receive_message_chain documentation 说的是“在未来的版本中可能会删除对 stub_chain 奇偶校验的支持”。从该文档链接到的问题清楚地表明,“存根链奇偶校验”意味着使用with 和receive_message_chain。所以请使用receive_message_chain;只是不要使用with。
-
如果您确实关心方法参数,请使用双精度数。例如,对于您提供的代码,
scope = double
allow(scope).to receive(:pluck).with(:a_field) { # return whatever }
allow(Model).to receive(:some_scope).with(no_args) { scope }