valk
valk

Reputation: 9874

How to write a stub with RSpec for a Rails method which calls a block and doesn't return value?

I have a function defined like this in my controller:

def respond_with(action = 0, &block)
  if block_given?
    response = get_response
    block.call( MyResponse.new(response) )
  end
end

With that I can query the response object:

respond_with do |response|
  case response.status
  when 'ok'
  when 'errors'
   #etc etc...
end

I can just call it without the block of course if I want.

If I had a function which returned a value it would be something like

controller.should_receive(:respond_with).with(DO_SOMETHING).and_return(something)

It would be ok for

def respond_with(action = 0)
  ...
  response
end

How do I check that the block is called with a specific value in the |response| ?

Upvotes: 1

Views: 1354

Answers (2)

Peter Alfvin
Peter Alfvin

Reputation: 29409

You use a "yield matcher" as described in https://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers/yield-matchers#yield-with-args-matcher

For example, you could do:

expect {|b| controller.respond_with(&b)}.to yield_with_args(MyResponse)

if you just wanted to check that the block was called exactly once with a MyResponse argument.

Upvotes: 1

valk
valk

Reputation: 9874

Instead of

.and_return(something) 

I use:

.and_yield(api_response_mock)

That does the job. And since the block get a response object, the gem rspec-mocks comes handy here.

Upvotes: 1

Related Questions