Mocking iteration over file in Python
Posted on Sat 24 December 2011 in Coding
Let’s say that I want to mock reading from a file using file’s iterator capability, i.e. (simplified version):
def readfile(f):
using open(f) as fd:
for line in fd:
yield line
I could mock the readfile function, but then my mock would have to
replicate the functionality of readfile, which as noted is somewhat
more complicated than the version above. Luckily, mock allows us to
mock the open function directly! The example in the documentation is
a little short on details, though. Here’s how to setup the mock for the
iterator case:
open_name = "some_module.open"
with patch(open_name, create=True) as open_mock:
open_mock.return_value = MagicMock(spec=file)
handle = open_mock.return_value.__enter__.return_value
handle.__iter__.return_value = iter(splitkeepsep(file_contents, "\n"))
The file_contents variable should contain the text of the file that’s
being mocked away, and the splitkeepsep function looks like this (see
also this post):
def splitkeepsep(s, sep):
return reduce(lambda acc, i: acc[:-1] + [acc[-1] + i] if i == sep else acc + [i], re.split("(%s)" % re.escape(sep), s), [])
That’s all there is to it! Happy mocking!