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
Why Can't Net::Ftp Connect to Server
Ruby-Open3.Popen3/How to Print The Output
Why Should @@Class_Variables Be Avoided in Ruby
Error While Starting Puma Server with Workers
Crontab Not Running Ruby Script
Typeerror: Can't Convert Net::Httpok into String
Will_Paginate Find Out If I'M on The Last Page
Error Installing Gems: Cannot Load Such File - Zlib
Ruby on Rails Query with Sum and Group
How to Handle Single Table Inheritance in Simpleform So a Single Helper Handles All Models
How to Test Helpers Blocks in Sinatra, Using Rspec
Where Is Ruby's Erb Format "Officially" Defined
Ruby/Rails 3.1: Given a Url String, Remove Path
Accessing Microsoft Exchange Server from Ruby
Set Ruby 2.0 Keyword Arguments with Attr_Accessor on Initialize
How to Add Values Dynamically to I18N