[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,

Michael

-- 
http://www.voidspace.org.uk/

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