Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RSpec: how to test file operations and file content

In my app, I have the following code:

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

I want to test this code via RSpec. What are the best practices for doing this?

like image 682
petRUShka Avatar asked Nov 01 '10 15:11

petRUShka


2 Answers

I would suggest using StringIO for this and making sure your SUT accepts a stream to write to instead of a filename. That way, different files or outputs can be used (more reusable), including the string IO (good for testing)

So in your test code (assuming your SUT instance is sutObject and the serializer is named writeStuffTo:

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

String IO behaves like an open file. So if the code already can work with a File object, it will work with StringIO.

like image 147
Danny Staple Avatar answered Sep 18 '22 23:09

Danny Staple


For very simple i/o, you can just mock File. So, given:

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

then:

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 

However, this approach falls flat in the presence of multiple reads/writes: simple refactorings which do not change the final state of the file can cause the test to break. In that case (and possibly in any case) you should prefer @Danny Staple's answer.

like image 26
Wayne Conrad Avatar answered Sep 21 '22 23:09

Wayne Conrad