Ruby 使用RSpec测试警告
是否有可能使用RSpec测试Ruby中的警告 像这样:Ruby 使用RSpec测试警告,ruby,testing,rspec,warnings,Ruby,Testing,Rspec,Warnings,是否有可能使用RSpec测试Ruby中的警告 像这样: class MyClass def initialize warn "Something is wrong" end end it "should warn" do MyClass.new.should warn("Something is wrong") end 警告在内核中定义,它包含在每个对象中。如果在初始化过程中没有发出警告,可以指定如下警告: obj = SomeClass.new obj.should_r
class MyClass
def initialize
warn "Something is wrong"
end
end
it "should warn" do
MyClass.new.should warn("Something is wrong")
end
警告
在内核
中定义,它包含在每个对象中。如果在初始化过程中没有发出警告,可以指定如下警告:
obj = SomeClass.new
obj.should_receive(:warn).with("Some Message")
obj.method_that_warns
expect { MyClass.new }.to warn("Something is wrong")
指定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
有一篇带有自定义期望的好文章正好解决了您的问题: 因此,它希望:
expect { MyClass.new }.to write("Something is wrong").to(:error)
基于这篇文章,您可以创建自己的期望,以便像这样使用它:
obj = SomeClass.new
obj.should_receive(:warn).with("Some Message")
obj.method_that_warns
expect { MyClass.new }.to warn("Something is wrong")
这是我的解决方案,我定义了一个自定义匹配器
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")
你能做
SomeClass.allocate
而不是SomeClass.new
,然后给它应该接收的,然后运行initialize吗?我在initialize
中用于警告的另一种方法是让我的类显式地调用内核.warn
(而不仅仅是warn
)。它不需要在内核上调用;它只需要在一些全局上调用,我可以在实例化之前设置一个应该_receive
。这是一个非常棒的答案,但我建议将文章的大部分放在答案中,以防文章失败。