[TIP] mock and patch

Andrea Crotti andrea.crotti.0 at gmail.com
Thu Mar 22 04:48:49 PDT 2012


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?



More information about the testing-in-python mailing list