I have a simple function that I'd like to test (perhaps mostly to appease simplecov). The function is:
module Utils
extend self
def blather(msg)
msg = "=== " + msg
STDERR.puts(msg)
Rails.logger.debug(msg)
end
end
The RSpec documentation for stubbing says that:
Messages can be stubbed on any class, including those in Ruby's core library.
But the following:
# file: spec/lib/utils_spec.rb
require 'spec_helper'
describe Utils do
context "blather" do
it "should print to STDERR" do
STDERR.any_instance.should_receive(:puts).with("=== zoo")
Utils.blather("zoo")
end
end
end
... I get an error
undefined method `any_instance' for #<IO:<STDERR>>
Putting aside questions as to whether this test makes any sense, is it possible to stub STDERR (the IO class)? Is this failing because it's a class method? Or is there a more sensible strategy for this kind of test?
Firstly, you should typically use $stderr
rather than STDERR
.
module Utils
extend self
def blather(msg)
msg = "=== " + msg
$stderr.puts(msg)
Rails.logger.debug(msg)
end
end
To answer your question, you can do the following in RSpec:
describe Utils do
context "blather" do
it "should print to stderr" do
$stderr.should_receive(:puts).with("=== zoo")
Utils.blather("zoo")
end
end
end
You just stub the method via $stderr.should_receive
. Because $stderr
is a normal object, you can stub methods on it like normal as well as set up expectations on it.