Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 558b9c4

Browse files
committed
Unit Test: Mock the open() builtin function on a specific filename
- input.txt gets mocked by test_input - All other files (like JSON) do not get mocked
1 parent c68b73f commit 558b9c4

File tree

1 file changed

+57
-2
lines changed

1 file changed

+57
-2
lines changed

‎lib/test.py‎

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,64 @@
11
import unittest
22
from unittest.mock import mock_open, patch
3+
from contextlib import contextmanager
4+
from io import StringIO
35
import solution
46

57

8+
class NotMocked(Exception):
9+
def __init__(self, filename):
10+
super(NotMocked, self).__init__(
11+
"The file %s was opened, but not mocked." % filename)
12+
self.filename = filename
13+
14+
15+
@contextmanager
16+
def mock_open(filename, contents=None, complain=True):
17+
"""Mock the open() builtin function on a specific filename
18+
.
19+
Let execution pass through to open() on files different than
20+
:filename:. Return a StringIO with :contents: if the file was
21+
matched. If the :contents: parameter is not given or if it is None,
22+
a StringIO instance simulating an empty file is returned.
23+
.
24+
If :complain: is True (default), will raise an AssertionError if
25+
:filename: was not opened in the enclosed block. A NotMocked
26+
exception will be raised if open() was called with a file that was
27+
not mocked by mock_open.
28+
29+
Source: https://mapleoin.github.io/perma/mocking-python-file-open
30+
"""
31+
open_files = set()
32+
33+
def mock_file(*args):
34+
if args[0] == filename:
35+
f = StringIO(contents)
36+
f.name = filename
37+
else:
38+
mocked_file.stop()
39+
f = open(*args)
40+
mocked_file.start()
41+
open_files.add(f.name)
42+
return f
43+
44+
mocked_file = patch('builtins.open', mock_file)
45+
mocked_file.start()
46+
try:
47+
yield
48+
except NotMocked as e:
49+
if e.filename != filename:
50+
raise
51+
mocked_file.stop()
52+
try:
53+
open_files.remove(filename)
54+
except KeyError:
55+
if complain:
56+
raise AssertionError("The file %s was not opened." % filename)
57+
for f_name in open_files:
58+
if complain:
59+
raise NotMocked(f_name)
60+
61+
662
class Test(unittest.TestCase):
763
def __init__(self, *args, **kwargs):
864
super(Test, self).__init__(*args, **kwargs)
@@ -17,8 +73,7 @@ def tearDown(self):
1773
print("")
1874

1975
def execute_test(self, test_input):
20-
mocked_open_function = mock_open(read_data=test_input)
21-
with patch("builtins.open", mocked_open_function):
76+
with mock_open('/input.txt', test_input, False):
2277
self.solution.calculate(True)
2378

2479
def get_solution(self, nr):

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /