2010-11-01 7 views
39

मेरे ऐप में मैं इस तरह के कोड के लिए कैसे:Rspec: फ़ाइल संचालन का परीक्षण करने और फाइल की सामग्री

File.open "filename", "w" do |file| 
    file.write("text") 
end 

मैं rspec के माध्यम से इस कोड का परीक्षण करना चाहते हैं। ऐसा करने के लिए सबसे अच्छा अभ्यास क्या है?

+0

@Wayne मैं सोच रहा हूँ कि कैसे आप testunit सी [इस सवाल] [1] [1] के साथ आगे बढ़ना होगा: http://stackoverflow.com/questions/11619884/ testunit-how-to-test-file-operation-and-file-content – netbe

उत्तर

53

मैं इसके लिए StringIO का उपयोग करने का सुझाव दूंगा और यह सुनिश्चित कर सकता हूं कि आपका एसयूटी एक फ़ाइल नाम के बजाय लिखने के लिए एक स्ट्रीम स्वीकार करता है। इस तरह से, अलग अलग फ़ाइलों या आउटपुट (अधिक पुन: प्रयोज्य), इस्तेमाल किया जा सकता स्ट्रिंग आईओ (परीक्षण के लिए अच्छा)

अपने परीक्षण कोड में

तो सहित (यह मानते हुए अपने SUT उदाहरण sutObject है और serializer writeStuffTo नाम है:

testIO = StringIO.new 
sutObject.writeStuffTo testIO 
testIO.string.should == "Hello, world!" 

स्ट्रिंग आईओ एक खुली फ़ाइल की तरह व्यवहार करता है। तो अगर कोड पहले से ही एक फ़ाइल वस्तु के साथ काम कर सकते हैं, यह बहुत ही सरल मैं के लिए StringIO साथ काम करेंगे।

+0

यह एक उत्कृष्ट उत्तर था। काश मैं आपको एक से अधिक बार ऊपर उठा सकता हूं। – Jazzepi

+1

अच्छा जवाब, मुझे पता है कि यह नहीं पूछा गया था, लेकिन अगर यह पार्टनर 'रीड' उदाहरण भी शामिल था तो यह सही होगा। –

+1

String.IO का उपयोग करने के लिए कोड को कैसे संशोधित करें? ऐसा लगता है कि परिणामी कोड बहुत अधिक होगा, बस इतना आसान है? –

44

/ओ, तो आप कर सकते हैं बस नकली फ़ाइल। तो, दिए गए :

def foo 
    File.open "filename", "w" do |file| 
    file.write("text") 
    end 
end 
तो

: सरल refactorings जो फ़ाइल की अंतिम अवस्था में परिवर्तन नहीं करते परीक्षण को तोड़ने के लिए पैदा कर सकता है:

describe "foo" do 

    it "should create 'filename' and put 'text' in it" do 
    file = mock('file') 
    File.should_receive(:open).with("filename", "w").and_yield(file) 
    file.should_receive(:write).with("text") 
    foo 
    end 

end 

हालांकि, इस पद्धति फ्लैट कई की उपस्थिति में गिर जाता है/लिखता पढ़ता है। उस मामले में (और संभवतः किसी भी मामले में) आपको @ डैनी स्टेपल के उत्तर को प्राथमिकता देना चाहिए।

17

आप fakefs का उपयोग कर सकते हैं।

यह स्टब्स फाइल सिस्टम और स्मृति

में फ़ाइलों को आप

File.exists? "filename" 

साथ जांचें कि फ़ाइल बनाया गया था बनाता है।

आप, साथ ही

File.open 

के साथ इसकी सामग्री पढ़ने और पर उम्मीद चला सकते हैं। मेरे जैसे कोई है जो एकाधिक निर्देशिका में एकाधिक फ़ाइलों को संशोधित करने की आवश्यकता के लिए

it 'How to mock File.open for write with rspec 3.4' do 
    @buffer = StringIO.new() 
    @filename = "somefile.txt" 
    @content = "the content fo the file" 
    allow(File).to receive(:open).with(@filename,'w').and_yield(@buffer) 

    # call the function that writes to the file 
    File.open(@filename, 'w') {|f| f.write(@content)} 

    # reading the buffer and checking its content. 
    expect(@buffer.string).to eq(@content) 
end 
+1

ध्यान दें कि FakeFS रुपयेपेक के साथ विफल रहता है (दोनों रुपये 2 और रुपेक 3) - https://github.com/fakefs/fakefs/issues/215 –

10

यह कैसे फ़ाइल (rspec 3.4 के साथ) उपहास करने के लिए है, तो आप एक बफर करने के लिए लिख सकते हैं और बाद में अपनी सामग्री की जांच कर सकता है उदाहरण के लिए रेल के लिए जनरेटर), मैं temp फ़ोल्डर का उपयोग करें।

Dir.mktmpdir do |dir| 
    Dir.chdir(dir) do 
    # Generate a clean Rails folder 
    Rails::Generators::AppGenerator.start ['foo', '--skip-bundle'] 
    File.open(File.join(dir, 'foo.txt'), 'w') {|f| f.write("write your stuff here") } 
    expect(File.exist?(File.join(dir, 'foo.txt'))).to eq(true) 
संबंधित मुद्दे