During RubyOffRails office hours, I was asked how we could test that puts
was called at the end of a method. Something like so:
def super_awesome_method
#...
puts the_thing
end
After discussing why the code was bad, we went about trying to use RSpec to assert that puts was actually called correct. One way would be to use StringIO to capture the value and ask it later, but that seemed a little sane for our tastes.
Instead, let's add a message expectation that puts
received the correct method call. But we couldn't quite add a should_receive
on Kernel. sooo:......
In IRB, you can simply redefine puts
>> def puts(*args)
>> super "yo"
>> end
=> nil
>> puts "OH HAI"
yo
=> nil
>>
But how to do this in RSpec? Kernel.module_eval could redefine puts, but does that do us any good?
YES! If we have it raise an error, and we could send along those args that we were given and test THOSE.
Crazy? or Crazy like a fox?
Or you could just do:
You can always set a mock expectation as long as you can get a reference to the object that is the receiver of the message. You are calling
method_that_calls_puts
onself
in the context of the example, so it in turn sendsputs
toself
, and you can mock it just fine.Alternately, if you want to mock the message on
Kernel
, you can do that, too:...you just have to explicitly send the
puts
message toKernel
.