2011-03-27 20 views
7

Bir şekilde RSpec kullanarak Ruby i uyarısı test etmek mümkün mü? Bunun gibiRSpec kullanarak uyarıları sınama

:

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

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

cevap

15

warn her nesnenin dahildir Kernel, tanımlanmıştır. Eğer başlatma sırasında uyarı yükselterek olmasaydı, bir böyle uyarı belirtebilirsiniz:

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

initialize yönteminde kaldırdı uyarı spec'ing oldukça daha karmaşıktır. Eğer yapılması gerekiyorsa, $stderr için sahte IO nesnesinde takas yapabilir ve inceleyebilirsiniz. Tam olarak senin sorunun çözer özel beklentisiyle iyi bir yazı yoktur

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

Bunun yerine SomeClass 'den SomeClass.allocate'' yapabilir miyiz:Bu benim CustomMatchers dahil sonra şimdi

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 

Takip olarak bu fonksiyonu kullanabilirsiniz özel bir eşleştirici has_warn benim çözüm tanımlamak edilir .new' ve sonra should_receive verin ve sonra başlatılamıyor? –

+0

"Başlatmada" uyarılar için kullandığım diğer yaklaşım, "Kernel.warn" adlı sınıf çağrımı açıkça (yalnızca 'uyarı' yerine) kullanmaktır. Çekirdeğe çağrılmasına gerek yoktur; Sadece bazı küresel üzerinde çağrılmadan önce bir 'should_receive 'ayarlayabileceğime çağırılmalı. –

4

Örneğin sonra geri emin olun: http://greyblake.com/blog/2012/12/14/custom-expectations-with-rspec/ Yani

o istiyorum: Bu konuda

expect { MyClass.new }.to write("Something is wrong").to(:error) 

Base Makale bunu kullanmak için kendi beklentinizi oluşturabilirsiniz:

expect { MyClass.new }.to warn("Something is wrong") 
+2

Bu müthiş bir cevaptır, ancak makalenin büyük kısmının makalenin aşağı inmesi durumunda yanıtın içine konmasını öneririm. – sunnyrjuneja

0
expect{ MyClass.new }.to has_warn("warning messages")