actor
actor copied to clipboard
Missing note on stubbing ServiceActor::Result
I'm trying to fake a service actor result in a Rails request spec. The test I would like to write looks like this:
context 'when search fails (e.g. because of HTTP 503 on Google side)' do
let(:params) { { query: 'Darkstorm Galaxy' } }
before do
allow(Google::AutocompletePlaces).to receive(:result).and_return(
instance_double(ServiceActor::Result, success?: false, error: 'lol')
)
end
it 'returns suggestions' do
get api_authenticated_address_search_suggestions_path, params: params, headers: auth_headers
expect(response).to have_http_status(:service_unavailable)
expect(response.parsed_body).to include('application_errors' => be_a(String))
end
end
But this doesn't work because error
is derived from method_missing
. And I shouldn't use double
because of RSpec best practices enforced by rubocop.
What's your take on that?
RSpec couldn’t be able to know what methods are defined on results since these methods only make sense at the end, once it’s passed through different actors.
For your example, it would make sense to define an error
method on ServiceActor::Result
for this specific use case, as it’s an encouraged output name:
class ServiceActor::Result
def error
to_h[:error]
end
end
However, this still wouldn’t work for other defined outputs.
You could use an instance_double
and stub expected outputs with allow
:
let(:result) { instance_double ServiceActor::Result, success?: false }
before do
allow(Google::AutocompletePlaces).to receive(:result).and_return(result)
allow(result).to receive(:error).and_return("lol")
end
In my case, though, I simply use double
in these cases and disable this cop, since it can’t know when we can and cannot check the methods beforehand:
RSpec/VerifiedDoubles:
# Allow the use of `double`.
Enabled: false
For those landing here but living on the minitest land: https://fidalgo.pt/2023/07/23/service-objects-in-the-wild.html (shameless plug)
Great thorough article! I’ve added it to the list of resources on the wiki
I’m closing this issue, but feel free to discuss/reopen if you think of a better way to handle this.