2014-04-10 53 views
0

我有一個這樣的類。如何使用RSpec測試文件IO是否按照時間進行更改

class Time 
    def has_same_hours?(t) 
    self.strftime("%Y%m%d%H") == t.strftime("%Y%m%d%H") 
    end 
end 
class MyLogger 
    DATA_DIR = 'data' 
    def initialize 
    @time_current_hour = Time.now 
    @io = nil 
    update_io_to_current_hour 
    end 
    def update_io_to_current_hour 
    @io = open output_filename, "a+" if @io.nil? 
    return if @time_current_hour.has_same_hours? Time.now 
    @io.close 
    @io = open output_filename, "a+" 
    @time_current_hour = Time.now 
    end 
    def output_filename(time = Time.now) 
    "#{DATA_DIR}/#{time.strftime('%Y_%m_%d_%H')}.txt" 
    end 
end 

update_io_to_current_hour被調用,文件IO應該如果小時是不同的比較@time_current_hour改變。

我想爲它寫RSpec測試。這是我寫的。

describe Logger do 
    let(:logger){ Logger.new } 
    describe "#update_io_to_current_hour" do 
    context "when the hour changes" do 
     before{ 
     @time_now = Time.parse("2010/4/10 19:00") 
     @time_current = Time.parse("2010/4/10 18:59") 
     Time.stub(:now).and_return(@time_now) 
     logger.stub(:time_current_hour).and_return(@time_current) 
     } 
     it "should change file io" do 
     expect{logger.update_io_to_current_hour}.to change{ logger.instance_variable_get :@io } 
     end 
    end 
    context "when the hour doesn't changes" do 
     before{ 
     @time_now = Time.parse("2010/4/10 18:59") 
     @time_current = Time.parse("2010/4/10 18:58") 
     Time.stub(:now).and_return(@time_now) 
     logger.stub(:time_current_hour).and_return(@time_current) 
     } 
     it "should not change file io" do 
     expect{logger.update_io_to_current_hour}.not_to change{ logger.instance_variable_get :@io } 
     end 
    end 
    end 
end 

第二次測試通過,第一次沒有。它看起來像文件io是永遠不會改變任何鑿到Time對象。

我在做什麼錯?我該如何正確編寫測試?

+1

是不是混淆命名方法has_same_hours?當你檢查正好相反時? – ejosafat

+0

你說得對,我應該用'=='來檢查而不是'!='。我不知道爲什麼我錯過了那種錯誤。我相應地編輯了我的問題。 – ironsand

回答

1

幾個要點:

logger.stub(:time_current_hour) 

類沒有名爲:time_current_hour方法,只有一個實例變量。測試實例變量的值很少有很好的理由;那是一個實現細節。你想測試行爲。無論如何,這個存根是無效的。另外

logger.instance_variable_get :@io 

現在,您正在進入對象的內部並檢查其內部值。你有沒有考慮到它的隱私? :)

我認爲這將是一件容易得多,如果你只是測試:output_filename的價值。當小時改變時,文件名改變。當小時相同時,文件名是相同的。

+0

所以,我不應該直接測試實例變量,我明白。我已經有了':output_filename'的測試,我將簡單地擺脫這個測試。感謝您的解釋! – ironsand

相關問題