11import unittest
22from unittest .mock import mock_open , patch
3+ from contextlib import contextmanager
4+ from io import StringIO
35import 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+ 662class 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