Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock os.walk in python with a temporary filesystem?

I'm trying to test some code that uses os.walk. I want to create a temporary, in-memory filesystem that I can populate with sample (empty) files and directories that os.walk will then return. This should save me the complexity of mocking os.walk calls to simulate recursion.

Specifically, the code I want to test is:

if recursive:     log.debug("Recursively searching for files under %s" % path)      for (dir_path, dirs, files) in os.walk(path):         log.debug("Found %d files in %s: %s" % (len(files), path, files))         for f in [os.path.join(dir_path, f) for f in files                   if not re.search(exclude, f)]:             yield f else:     log.debug("Non-recursively searching for files under %s" % path)      for (dir_path, dirs, files) in os.walk(path):         log.debug("Found %d files in %s: %s" % (len(files), path, files))         for f in [os.path.join(dir_path, f) for f in files                     if not re.search(exclude, f)]:             yield f 

Is this possible in python?

like image 683
jbrown Avatar asked Jul 02 '14 14:07

jbrown


People also ask

How do you make a mock in Python?

If you want to mock an object for the duration of your entire test function, you can use patch() as a function decorator. These functions are now in their own file, separate from their tests. Next, you'll re-create your tests in a file called tests.py .

How do you mock JSON in Python?

If you have a Python object, you can convert it into a JSON string by using the json.dumps() method.

How do you use mock exception in Python?

Just assign the exception to side_effect instead: mockedObj. raiseError. side_effect = Exception("Test") . You don't have to no: and his edit has a third way of doing it where he is making a Mock with the side effect set, but its still a valid, and good thing to know how to do in testing.


1 Answers

No. os.walk() is constructed entirely around os.listdir(), with assistance of os.path.islink() and os.path.isdir(). These are essentially system calls, so you'd have to mock your filesystem at the system level. Unless you want to write a FUSE plugin this is not going to be easy to mock.

All os.walk() needs to return is a list of tuples, really. Unless you are testing manipulating the dirs component, it couldn't be more simple:

with mock.patch('os.walk') as mockwalk:     mockwalk.return_value = [         ('/foo', ('bar',), ('baz',)),         ('/foo/bar', (), ('spam', 'eggs')),     ] 

This would mock the following directory structure:

/foo  ├── baz  └── bar       ├── spam      └── eggs 
like image 146
Martijn Pieters Avatar answered Oct 02 '22 12:10

Martijn Pieters