在某种程度上可以使用RSpec测试Ruby的警告吗?
像这样:
class MyClass
def initialize
warn "Something is wrong"
end
end
it "should warn" do
MyClass.new.should warn("Something is wrong")
end
答案 0 :(得分:16)
warn
在Kernel
中定义,包含在每个对象中。如果您在初始化期间没有提出警告,则可以指定如下警告:
obj = SomeClass.new
obj.should_receive(:warn).with("Some Message")
obj.method_that_warns
在initialize
方法中引发警告要复杂得多。如果必须这样做,您可以交换假IO
对象$stderr
并检查它。请务必在示例
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
答案 1 :(得分:6)
有一篇关于自定义期望的好文章可以解决您的问题:http://greyblake.com/blog/2012/12/14/custom-expectations-with-rspec/
所以它想:
expect { MyClass.new }.to write("Something is wrong").to(:error)
根据那篇文章,你可以创建自己的期望,就像这样使用它:
expect { MyClass.new }.to warn("Something is wrong")
答案 2 :(得分:-1)
这是我的解决方案,我定义了一个自定义匹配器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
现在,您可以在包含CustomMatchers后使用此功能:
expect{ MyClass.new }.to has_warn("warning messages")