I have a proprietary repository format and I'm trying to develop a Python module to process these repositories. Repo format goes as:
/home/X/
|
+ alpha/
|
+ beta/
|
+ project.conf
Here, X
is a project. alpha
and beta
are folders inside this project and they represent groups in this project. A group is a container in this repo and what it represents is really not relevant for this question. The repo X
also has files in its root level; project.conf
is an example of such a file.
I have a class called Project
that abstracts projects such as X
. The Project
class has a method load()
that builds an in-memory representation.
class Project(object):
def load(self):
for entry in os.listdir(self.root):
path = os.path.join(self.root, entry)
if os.path.isdir(path):
group = Group(path)
self.groups.append(group)
group.load()
else:
# process files ...
To unit test the load()
method by mocking the file system, I have:
import unittest
from unittest import mock
import Project
class TestRepo(unittest.TestCase):
def test_load_project(self):
project = Project("X")
with mock.patch('os.listdir') as mocked_listdir:
mocked_listdir.return_value = ['alpha', 'beta', 'project.conf']
project.load()
self.assertEqual(len(project.groups), 2)
This does mock os.listdir
successfully. But I can't trick Python to treat mocked_listdir.return_value
as consisting of files and directories.
How do I mock either os.listdir
or os.path.isdir
, in the same test, such that the test will see alpha
and beta
as directories and project.conf
as a file?
I managed to achieve the desired behavior by passing an iterable to the side_effect
attribute of the mocked isdir
object.
import unittest
from unittest import mock
import Project
class TestRepo(unittest.TestCase):
def test_load_project(self):
project = Project("X")
with mock.patch('os.listdir') as mocked_listdir:
with mock.patch('os.path.isdir') as mocked_isdir:
mocked_listdir.return_value = ['alpha', 'beta', 'project.conf']
mocked_isdir.side_effect = [True, True, False]
project.load()
self.assertEqual(len(project.groups), 2)
The key is the mocked_isdir.side_effect = [True, True, False]
line. The boolean values in the iterable should match the order of directory and file entries passed to the mocked_listdir.return_value
attribute.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With