How to Test for File Operations with FakeFS and RSpec
Background:
Say you have controller method that creates and writes into a file and you’d like to be able to run expectations on the behavior and not so much of the implementation.
The normal way would be to do something like:
def test_creates_directory
FileUtils.expects(:mkdir).with("directory").once
Library.add "directory"
end
because this just doesn’t work.
def test_creates_directory
Library.add "directory"
assert File.directory?("directory")
end
So one way to solve this is with this gem called FakeFS. The code snippet above, is taken from their documentation.
FakeFS stubs your Filesystem and allows you to perform expectations by interacting directly with files that were created without actually creating and messing up your actual Rails.root.
Lets start:
Step 1: Setup the Gem
# Gemfile
gem "fakefs", :require => "fakefs/safe"
Step 2: Activate FakeFS in the tests that requires it
In your /spec_file, include the various helpers:
# /spec/model/your_spec.rb
require 'fakefs/spec_helpers'
describe YourModel do
include FakeFS::SpecsHelper
end
Step 3: Write your tests!
# /spec/model/your_spec.rb
require 'fakefs/spec_helpers'
describe YourModel do
include FakeFS::SpecsHelper
it "should return a file with its content having a line length of 140 characters" do
# This is like the first safety check. Run this before your File Operations
FakeFS.activate!
# This is something special, it will take a while to load everytime you run
# the test, so don't panic if you're wondering why it appears that the test
# is "stuck". This stubs your existing Filesystem.
FakeFS::FileSystem.clone(Rails.root)
file = generate_file_and_return_filename("magic_happens_here")
File.readlines(file).each do |line|
expect(line.length).to eq(141)
end
FakeFS.deactivate!
end
end
And you’re done! Now you have a perfectly stubbable Filesystem, which doesn’t actually create and save the file into your actual Rails Environment.
Cheers!