Stubbing Dry::Matcher cases in Rails/RSpec

662 views Asked by At

We are using Dry::Monads with Dry::Matchers in our app. We mostly consume monadic results at the controller level using the Dry::Matchers case syntax like so:

....call(foo: bar) do |result|
 result.success { |resource| render json: resource, status 200 }
 result.failure { |error| render json: error, status: 422 }
end

In the above case we test this with an integration test, so no need to stub anything.

There are cases where we would like to use the above block syntax to process a monadic response at an interim step in our workflow so we'd like to stub/mock the above result but not stub out the block. The one way we've found success is:

let(:validator) do
  instance_spy(Validator, call: validator_response).tap do |spy|
    spy.singleton_class.include Dry::Matcher.for(:call, with: Dry::Matcher::ResultMatcher)
  end
end
let(:validator_response) { Success(...) } # or Failure(...)

However this feels like a very heavy-handed spy. Has anyone encountered this use case? Is this a bad idea in general? The alternative would be to process the monadic response with case statement which works just as well but is not as nice to look at.

0

There are 0 answers