简体   繁体   中英

How to python mock patch the open method in multiple files

I am looking for a way to do something like patch.specialmultiple below, Where I want to patch, say the open method in multiple files with the same Mock object instance. Also so the when used as a decorator, there is only mock object passed to the decorated function

Is there a way to do this with mock

file1.py
---------
def hello():
    open('test.data').read()

file2.py
--------
def world():
    open('test2.data').read()

file3.py
--------
mopen = mock.MagicMock(create=True)
@patch.specialmultiple(['file1.open', 'file2.open'], new=mopen)
def test_case1(mopen):
    open.side_effect = [OSError('not found'), OSError('Noy found')]

There is no direct way to do what you want. The easiest way is using multiline patch decorator and mock_open to mock open :

m = mock.MagicMock(side_effect=OSError('not found'))    
mopen = mock.mock_open(m)

@mock.patch('file1.open', mopen, create=True)
@mock.patch('file2.open', mopen, create=True)
def test_case():
    with self.assertRaises(OSError):
        hello1()

    mopen.side_effect = IOError('er')
    with self.assertRaises(IOError):
        hello2()

You should be able to patch open on the __builtin__ ( builtins on python3.x) module.

>>> import __builtin__
>>> import mock
>>> p = mock.patch.object(__builtin__, 'open')
>>> p.start()
<MagicMock name='open' id='4331984720'>
>>> open
<MagicMock name='open' id='4331984720'>
>>> p.stop()
>>> open
<built-in function open>

Of course, this will patch it everywhere . There isn't a way to whitelist a set of specific modules for this case...

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM