There are two problems in your code. First, the test_code.py file is called twice - first when you call it, and then again when mock
imports it for the purpose of creating a patch. So you should change it as follows:
def f():
return 'unpatched'
import patch_stuff
if __name__ == "__main__":
patch_stuff.patch_it_up()
print f()
This will print only the 'unpatched'
string. Which leads to the second thing: the documentation suggests that this not how the patchers work. When you call the start
method it returns the patched object to be used. So the expected output can be achieved with the following modifications:
patch_stuff.py
from mock import patch
def patch_it_up():
p = patch('test_code.f')
m = p.start()
m.return_value = 'patched'
return m
test_code.py
def f():
return 'unpatched'
import patch_stuff
if __name__ == "__main__":
m = patch_stuff.patch_it_up()
print m()
This will print the expected 'patched'
string.
This makes this scenario not very practical, but all the examples in the documentation show only the possibility of modifying modules imported in the current context. E.g., this will also work:
from mock import patch
def patch_it_up():
import test_code
p = patch('test_code.f')
m = p.start()
m.return_value = 'patched'
print "inside patch_it_up:", test_code.f()