Reputation: 3213
I have a statement like Model.some_scope.pluck(:a_field)
in a method I'd like to test.
What's the recommended way for me to stub the return value of this chained method call statement with rspec-mocks 3.4.0? I saw that stub_chain
and receive_message_chain
are both listed as old syntax on the RSpec website.
Best Regards.
Upvotes: 2
Views: 2592
Reputation: 37607
The cleanest way to test that code is to extract a method, e.g.
class Model < ActiveRecord::Base
def self.some_scope_fields
some_scope.pluck(:a_field)
end
end
That method can be stubbed without a chain.
However, there are times when it's neither convenient nor idiomatic to do that. For example, it's idiomatic, and not a Law of Demeter violation, to call create
on an ActiveRecord model's association methods. In those cases,
if you don't care about method arguments, use receive_message_chain
. stub_chain
is deprecated; receive_message_chain
is not. What the receive_message_chain
documentation says is that "support for stub_chain parity may be removed in future versions". The issue linked to from that documentation makes it clear that "stub chain parity" means the use of with
with receive_message_chain
. So do use receive_message_chain
; just don't use with
with it.
if you do care about method arguments, use doubles. For example, for the code you gave,
scope = double
allow(scope).to receive(:pluck).with(:a_field) { # return whatever }
allow(Model).to receive(:some_scope).with(no_args) { scope }
Upvotes: 3