Python mock: patching
From wikinotes
mock.patch
Patching allows you to target a specific function by it's module-path.
import unittest import mock class Test_First(unittest.TestCase): def test_myotherfunc_wascalled(self): with mock.patch( 'os.path.isfile', return_value=True ) as _mock_myotherfunc: ClassImTesting()
mock.patch.object
with mock.patch.object(os.path, 'isfile', return_value=True): os.path.isfile('/not/a/file')
mock.patch.dict
with mock.patch.dict('os.environ', {'TEST': '1'}): os.environ['TEST']
decorator
In order to avoid nesting
with mock.patch
statements
(and indenting to infinity), you can use a decorator on your unittest,
then modify your mock object's attributes for return-values etc.
This method of mocking is much more readable when things get very complex.class TestExample(unittest.TestCase): @mock.patch('os.path') @mock.patch('os.stat') def test_patching(self, mock_stat, mock_path): os.path.return_value = True ClassImTesting()
mock a class and multiple methods
Only mock methods, leaving class intact.
with mock.patch.object(MyClass, 'methodA', return_value='a'): with mock.patch.object(MyClass, 'methodB', return_value='b'): MyClass().methodA() MyClass().methodB()Mock entire class, and modify methods.
def test_myclass(): ns = myclass.__name__ with mock.patch( '{}.MyClass'.format(ns) ) as mock_myclass: # method A mock_mycls.return_value.do_something = mock.Mock(return_value='new return!') # method B mock_mycls().do_something = mock.Mock(return_value='new_return')https://stackoverflow.com/questions/41627576/python-mock-patch-multiple-methods-in-a-class
mock any instance of a class
@mock.patch('foo.Bar') def test_something(self, m_cls): m_inst = mock.Mock() m_cls.return_value = m_inst m_inst.start.assert_called_with('cat')
mock a context-manager
The trick is to mock `__enter__` , and it's return value.
with mock.patch('zipfile.ZipFile') as mock_zip: mock_ziparchive = mock.Mock() mock_ziparchive.return_value.namelist.return_value = ['a/b.txt'] mock_zip.return_value.__enter__ = mock_ziparchivewill mock the following
with zipfile.ZipFile('a/b.zip', 'r') as archive: print(archive.namelist()) >>> ['a/b.txt']
mock attribute
getmodules = mock.PropertyMock(return_value={}) with mock.patch.object(sys, 'modules', new_callable=getmodules): print(sys.modules)
mock import
Mocking imports depends on the style of import.
from X import Y
imports attribute Y from the mock object Ximport X.Y
imports Y directly
# from maya import cmds maya_cmds = mock.MagicMock() maya_cmds.about = mock.Mock(return_value='2015') maya = mock.MagicMock() maya.cmds = maya_cmds sys.modules['maya'] = mock_maya# import maya.cmds maya_cmds = mock.Mock() maya_cmds.about = mock.Mock(returnvalue='2015') sys.modules['maya.cmds'] = mock_maya_cmds