Skip to content

Instantly share code, notes, and snippets.

@gnufied
Created May 28, 2012 09:16
Show Gist options
  • Save gnufied/2818094 to your computer and use it in GitHub Desktop.
Save gnufied/2818094 to your computer and use it in GitHub Desktop.
How to chain method expectations in rspec-2
class Object
def should_chain_receive(*args,&block)
if block_given?
ChainReceive.new(self,args,block)
else
ChainReceive.new(self,args)
end
end
end
class ChainReceive
attr_accessor :current_object
attr_accessor :block
def initialize(base_object,args,block = nil)
self.current_object = base_object
if block
set_mock_chain(args[0..-2])
result = block.call()
current_object.should_receive(args.last).and_return result
else
set_mock_chain(args)
end
self
end
def then(method, options = {},&block)
if block_given?
result = block.call()
set_then_chain(method,result,options)
else
set_then_chain(method,Object.new(),options)
end
self
end
private
def set_mock_chain(args)
args.each do |argument|
temp = Object.new()
self.current_object.should_receive(argument).and_return(temp)
self.current_object = temp
end
end
def set_then_chain(method,result,options)
if options[:with]
self.current_object.should_receive(method).with(*options[:with]).and_return(result)
self.current_object = result
else
self.current_object.should_receive(method).and_return(result)
self.current_object = result
end
end
end
# usage
User.should_chain_receive(:active, :paid) { active_paid_users }
User.should_chain_receive(:active).then(:paid, :with => [:amount => 20 ]) { active_paid_users }
@readysetawesome
Copy link

I had a similar idea but wanted to keep things super tight when there is a chain of expectations with args being passed to a method somewhere in the middle....

https://gist.github.com/readysetawesome/5062199

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment