Mocking Directory Structure in Python
Question: I have some code below that I'm using to take an input of files, open and
process, and then output some data. I've gotten the functionality working and
I'm unit testing it now, below is an example of the code.

    
    
    def foo(dir):
        path_to_search = join(dir, "/baz/foo")
    
       if isdir(path_to_search): 
       #path exists so do stuff...
    
            for fname in listdir(path_to_search):
                do_stuff()
    
       else:
           print "path doesn't exist"
    

I've been able to create a test where the past doesn't exist easily enough,
but as you can see above I assert that the "/baz/foo" portion of the directory
structure exists (in production the directory structure must have this file,
in some cases it won't and we won't need to process it.)

I've tried to create a temporary directory structure using TempDir and join,
but the code always kicks out saying the path doesn't exists.

Is it possible to mock the output of os.listdir such that I won't need to
create a temporary directory structure that follows the needed /baz/foo
convention?


Answer: You don't need to create a fake directory structure, all you need to do is
mock the `isdir()` and `listdir()` functions.

Using the [`unittest.mock`
library](https://docs.python.org/3/library/unittest.mock.html) (or the
external [`mock` library](http://www.voidspace.org.uk/python/mock/), which is
the exact same thing for Python versions < 3.3):

    
    
    try:
        # Python >= 3.3 
        from unittest import mock
    except ImportError:
        # Python < 3.3
        import mock
    
    with mock.patch('yourmodule.isdir') as mocked_isdir, \
            mock.patch('yourmodule.listdir') as mocked_listdir:
        mocked_isdir.return_value = True
        mocked_listdir.return_value = ['filename1', 'filename2']
    
        yourmodule.foo('/spam/eggs')
    
        mocked_isdir.assert_called_with('/spam/eggs/baz/foo')
        mocked_listdir.assert_called_with('/spam/eggs/baz/foo')
    

