Fake Filesystem for Ruby

Mock filesystem in integration testing

Maybe this won't answer your question directly, but in such cases I tend to create a temporary directory during test setup and remove it on teardown. Of course you also have to ensure the application writes to this temporary directory. I always have a configuration option defining destination directory that I can overwrite during testing.

When it comes to assertions I use plain File.exist? or File.directory?, but of course you can create your own wrappers around it. If you need some initial state you can build a directory that can be used as a fixture and will be copied to the temporary direcory during test setup.

FakeFS and Rspec incosistency with Rspec and real filesystem

I found the answer just after creating that question, duh ;) I've looked into source of that lib and found suspicious line.

Instead of FakeFS::SpecHelpers I've included FakeFS::SpecHelpers::All which is the same code except FakeFS::FileSystem is not being cleared after each call, now it behaves correctly.

How simulate system users for testing file system interactions in ruby?

I'm not sure I get the question, but I assume you want to test the "real" results of the FileUtils calls, i.e. changed permissions and ownership of files, that's why you need some kind of users. I wouldn't do that, since "SELECT isn't broken": http://pragmatictips.com/26

Instead, assume the following: if you call FileUtils.chown and friends with the right parameters, they will do the right thing. To make sure your application passes the correct parameters to FileUtils, use a mock. Here's an example: https://gist.github.com/phillipoertel/5020102

If you don't want to couple your test so closely to the implementation (the mock knows what's going on in your class internally) you could test the changed permissions by expecting it's effects. For example: if @user wasn't allowed to access @file before, call the method which changes permissions, then call one of your methods which require the changed permissions and assert that works. But this approach will access the filesystem, which you didn't want in the first place.

How to create a fake filesystem that forwards system calls to my program?

FUSE is what you're looking for, in principle. One implementation of the archive-mounting you're looking for is/was archive mount, but I am unsure how well it is maintained.

Rspec Ruby on Rails Test File System in model

Quick answer: you can stub out model methods like any others. Either stub a specific instance of a model, and then stub find or whatever to return that, or stub out any_instance to if you don't want to worry about which model is involved. Something like:

it "does something" do
foo = Foo.create! some_attributes
foo.should_receive(:some_method).and_return(whatever)
Foo.stub(:find).and_return(foo)
end

The real answer is that your code is too complicated to test effectively. Your models should not even know that a filesystem exists. That behavior should be encapsulated in other classes, which you can test independently. Your model's after_save can then just call a single method on that class, and testing whether or not that single method gets called will be a lot easier.

Your methods are also very difficult to test, because they are trying to do too much. All that conditional logic and external dependencies means you'll have to do a whole lot of mocking to get to the various bits you might want to test.

This is a big topic and a good answer is well beyond the scope of this answer. Start with the Wikipedia article on SOLID and read from there for some of the reasoning behind separating concerns into individual classes and using tiny, composed methods. To give you a ballpark idea, a method with more than one branch or more than 10 lines of code is too big; a class that is more than about 100 lines of code is too big.

How to test directory?

My suggestion is to stub and mock out the behavior of the internal things: Something like

Dir.stub(:new).with(path).and_return([list of File mocks?])

This way you can be sure you are only testing your code and not the code from the various ruby libraries you're using.

I find myself doing this with things like http based behavior. If I'm using the ruby http libraries not only do I not want to waste time testing those things but it's expensive to actually fire off http requests and wait for responses. Stubbing those things out allows me to test how my code reacts to certain response types.

I think it's all about isolation.



Related Topics



Leave a reply



Submit