2011-03-27 78 views
7

是否有可能使用RSpec測試警告我Ruby?使用RSpec進行警告測試

像這樣:

class MyClass 
    def initialize 
    warn "Something is wrong" 
    end 
end 

it "should warn" do 
    MyClass.new.should warn("Something is wrong") 
end 

回答

15

warnKernel,它包括在每一個對象定義。如果你不提高初始化過程中的警告,你可以指定一個像這樣的警告:

obj = SomeClass.new 
obj.should_receive(:warn).with("Some Message") 
obj.method_that_warns 

Spec'ing在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 
+0

你知道'SomeClass.allocate'而不是'SomeClass的.new',然後給它的should_receive,然後運行初始化? – 2011-10-20 06:08:09

+0

我在'initialize'中用於警告的另一種方法是讓我的類明確地調用Kernel.warn(而不是'warn')。它不需要在內核上調用;它只需要在一些全局上調用,我可以在實例化之前設置一個'should_receive'。 – 2011-11-11 16:46:35

4

有定製期望的好文章解決了究竟你的問題的例子後恢復: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

這是一個非常棒的答案,但我會建議將文章的大部分放在答案中,以防文章發生故障。 – sunnyrjuneja 2014-03-10 07:10:12

0

這是我的解決方案,我自定義一個匹配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")