使用RSpec测试警告
是否有可能使用RSpec测试Ruby的警告?
像这样:
class MyClass def initialize warn "Something is wrong" end end it "should warn" do MyClass.new.should warn("Something is wrong") end
warn
在Kernel
定义,它包含在每个对象中。 如果您在初始化期间未提出警告,则可以指定如下警告:
obj = SomeClass.new obj.should_receive(:warn).with("Some Message") obj.method_that_warns
在initialize
方法中引发警告是非常复杂的。 如果必须这样做,您可以为$stderr
交换一个伪IO
对象并检查它。 请务必在示例后恢复它
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
有一篇关于自定义期望的好文章可以解决您的问题: 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")
这是我的解决方案,我定义了一个自定义匹配器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后使用此function:
expect{ MyClass.new }.to has_warn("warning messages")