Is it somehow possible to test warnings i Ruby using RSpec?
Like this:
class MyClass
def initialize
warn "Something is wrong"
end
end
it "should warn" do
MyClass.new.should warn("Something is wrong")
end
Is it somehow possible to test warnings i Ruby using RSpec?
Like this:
class MyClass
def initialize
warn "Something is wrong"
end
end
it "should warn" do
MyClass.new.should warn("Something is wrong")
end
warn is defined in Kernel, which is included in every object. If you weren't raising the warning during initialization, you could specify a warning like this:
obj = SomeClass.new
obj.should_receive(:warn).with("Some Message")
obj.method_that_warns
Spec'ing a warning raised in the initialize method is quite more complex. If it must be done, you can swap in a fake IO object for $stderr and inspect it. Just be sure to restore it after the example
class MyClass
def initialize
warn "Something is wrong"
end
end
describe MyClass do
before do
@orig_stderr = $stderr
$stderr = StringIO.new
end
it "warns on initialization" do
MyClass.new
$stderr.rewind
$stderr.string.chomp.should eq("Something is wrong")
end
after do
$stderr = @orig_stderr
end
end
There is a good article with custom expectation which solves exactly your problem: http://greyblake.com/blog/2012/12/14/custom-expectations-with-rspec/
So it would like:
expect { MyClass.new }.to write("Something is wrong").to(:error)
Base on that article you can create you own expectation to use it like this:
expect { MyClass.new }.to warn("Something is wrong")
If warning raises during initialization you can use output expectation:
expect do
described_class.new
end.to output('test message').to_stderr
This is my solution, I define a custom matcher has_warn
require 'rspec'
require 'stringio'
module CustomMatchers
class HasWarn
def initialize(expected)
@expected = expected
end
def matches?(given_proc)
original_stderr = $stderr
$stderr = StringIO.new
given_proc.call
@buffer = $stderr.string.strip
@expected.include? @buffer.strip
ensure
$stderr = original_stderr
end
def supports_block_expectations?
true
end
def failure_message_generator(to)
%Q[expected #{to} get message:\n#{@expected.inspect}\nbut got:\n#{@buffer.inspect}]
end
def failure_message
failure_message_generator 'to'
end
def failure_message_when_negated
failure_message_generator 'not to'
end
end
def has_warn(msg)
HasWarn.new(msg)
end
end
now you can use this function as follow after include the CustomMatchers:
expect{ MyClass.new }.to has_warn("warning messages")