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!