[TIP] mock and patch

Michael Foord michael at voidspace.org.uk
Thu Mar 22 04:51:04 PDT 2012

On 22/03/2012 11:48, Andrea Crotti wrote:
> On 03/22/2012 11:23 AM, Michael Foord wrote:
>> On 22/03/2012 10:37, Andrea Crotti wrote:
>>> I was reading the doc at
>>> http://www.voidspace.org.uk/python/mock/patch.html#where-to-patch
>>> and so I tried this simple example, which I though would fail, because
>>> from the doc I should instead patch 'module.getcwd' instead of
>>> 'os.getcwd'.
>>> from os import getcwd
>>> @mock.patch('os.getcwd')
>>> def mycwd(_):
>>>     print(os.getcwd())
>>> mycwd()
>>> <MagicMock name='getcwd()' id='32916368'>
>>> But the patch actually works perfectly anyway, so am I misunderstanding
>>> the doc or maybe it's not updated to the last (smarter) behaviour of 
>>> the
>>> mock library?
>> The key to patching is that you patch *where the object is looked 
>> up*. If you call "os.getcwd()" then you are looking up the "getcwd" 
>> function on the os module. It doesn't matter where you import "os", 
>> if you do "os.getcwd" then you are looking up "getcwd" on the os 
>> module. So directly in the os module is the right place to patch.
>> The alternative scenario is where you do "from os import getcwd" and 
>> then call "getcwd()" directly. In this case "getcwd" will be looked 
>> up in the module that imported it - and *then* you have to patch it 
>> in the module instead of in os.
> Ah good thanks now it's more clear :)
> As a curiosity, would it be possible to make @patch even more magic, 
> so  make it patch the right thing?
> Something like (just guessing) looking in globals() and locals() if 
> that name is defined, remove it from there
> and patch the original module?
Look in globals() and locals() where? patch needs to know *where* to do 
the patching, it's about as magic as it can usefully get. Python modules 
are nicely separated as namespaces, patch allows you patch names within 
a namespace - but you have to specify the namespace.

All the best,



May you do good and not evil
May you find forgiveness for yourself and forgive others
May you share freely, never taking more than you give.
-- the sqlite blessing http://www.sqlite.org/different.html

More information about the testing-in-python mailing list