I have two files:
#file1.py
def_writefile():
...
fp = open('file')
fp.write('blah')
...
#file2.py
file1.writefile()
I've tried patching open different ways:
#test_file.py
fn = mock.mock_open()
with mock.patch('__builtin__.open', fn):
file1.writefile()
with mock.patch('file1.open', fn):
file1.writefile()
with mock.patch('file2.open', fn):
file1.writefile()
with mock.patch('__main__.open', fn, create=True):
file1.writefile()
assert(mock_file().write.called_once_with('blah'))
But none of them seem to work. What is the correct way to patch a builtin like open from an imported module using mock?
You want this:
import file1
fn = mock.mock_open()
with mock.patch('file1.open', fn, create=True):
file1.writefile()
fn().write.assert_called_once_with('blah')
You need to mock the open
function that will be used in file1.py
, so we pass 'file1.open'
isntead of '__main__.open'
. The other piece you were missing is that you weren't using the right function to make sure write
was called with the correct parameters - you need to use the assert_called_once_with
function that's built into the Mock
class.
create=True
is required because the open
function won't be found in the file1
class at import time, because the open
function won't actually be pulled into the module until runtime. Normally that means mock
will thrown an exception saying file1
is missing the attribute. Adding create=True
makes mock
create the attribute when it doesn't find it, and is mentioned in the docs as being useful for this situation:
This is useful for writing tests against attributes that your production code creates at runtime
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.