mockfs.rb

Path: mockfs.rb
Last Update: Sun Jun 11 17:33:17 EDT 2006

MockFS is a test-obsessed library for mocking out the entire file system. It provides mock objects that clone the functionality of File, FileUtils, Dir, and other in-Ruby file-access libraries.

To use MockFS in your production code, call MockFS.[ class ].

  MockFS.file               => File
  MockFS.file_utils         => FileUtils
  MockFS.dir                => Dir
  MockFS.dir.entries( '.' ) => [".", "..", ...]

Then, to turn these into mock instances for a test case, simply call

  MockFS.mock = true

When you’ve done this, the normal calls will actually return adapters that pretend to be the class in question:

  MockFS.file               => MockFS::FileAdapter
  MockFS.file_utils         => MockFS::FileUtilsAdapter
  MockFS.dir                => MockFS::DirAdapter
  MockFS.dir.entries( '.' ) => [".", "..", ...]

You can get direct access to the enclosed MockFileSystem by calling MockFS.mock_file_system.

Testing example

For example, let’s test a simple function that moves a log file into somebody’s home directory.

  require 'mockfs'

  def move_log
    MockFS.file_utils.mv( '/var/log/httpd/access_log', '/home/francis/logs/' )
  end

A test of this functionality might look like this:

  require 'test/unit'

  class TestMoveLog < Test::Unit::TestCase
    def test_move_log
      # Set MockFS to use the mock file system
      MockFS.mock = true

      # Fill certain directories
      MockFS.fill_path '/var/log/httpd/'
      MockFS.fill_path '/home/francis/logs/'

      # Create the access log
      MockFS.file.open( '/var/log/httpd/access_log', File::CREAT ) do |f|
        f.puts "line 1 of the access log"
      end

      # Run the method
      move_log

      # Test that it was moved, along with its contents
      assert( MockFS.file.exist?( '/home/francis/logs/access_log' ) )
      assert( !MockFS.file.exist?( '/var/log/httpd/access_log' ) )
      contents = MockFS.file.open( '/home/francis/logs/access_log' ) do |f|
        f.gets( nil )
      end
      assert_equal( "line 1 of the access log\n", contents )
    end
  end

This test will be successful, and it won’t litter your real file-system with testing files.

override.rb

Reading the testing example above, you may be struck by one thing: Using MockFS requires you to remember to reference it everywhere, making calls such as MockFS.file_utils.mv instead of just FileUtils.mv. As another option, you can use File, FileUtils, and Dir directly, and then in your tests, substitute them by including mockfs/override.rb. I’d recommend using these with caution; substituting these low-level classes can have unpredictable results.

Including override.rb also allows Kernel.require to look in your mock file system for mock Ruby files to include. You might find this useful if you have configuration files written in Ruby, and you’d like to swap them out for tests. This is pretty experimental, too.

Project page

You can view the Rubyforge project page at rubyforge.org/projects/mockfs.

Required files

delegate   extensions/all   fileutils   singleton  

[Validate]