How to mock a function defined in a module of a package?
I've got a following structure:
|-- dirBar
| |-- __init__.py
| |-- bar.py
|-- foo.py
`-- test.py
bar.py
def returnBar():
return 'Bar'
foo.py
from dirBar.bar import returnBar
def printFoo():
print returnBar()
test.py
from mock import Mock
from foo import printFoo
from dirBar import bar
bar.returnBar = Mock(return_value='Foo')
printFoo()
the result of python test.py
is Bar
.
How to mock the printBar
to make it return Foo
so that printFoo
will print it?
EDIT: Without modifying any other file that test.py
Solution 1:
I'm guessing you are going to mock the function returnBar
, you'd like to use patch
decorator:
from mock import patch
from foo import printFoo
@patch('foo.returnBar')
def test_printFoo(mockBar):
mockBar.return_value = 'Foo'
printFoo()
test_printFoo()
Solution 2:
Just import the bar
module before the foo
module and mock it:
from mock import Mock
from dirBar import bar
bar.returnBar = Mock(return_value='Foo')
from foo import printFoo
printFoo()
When you are importing the returnBar
in foo.py
, you are binding the value of the module to a variable called returnBar
. This variable is local so is put in the closure of the printFoo()
function when foo
is imported - and the values in the closure cannot be updated by code from outiside it. So, it should have the new value (that is, the mocking function) before the importing of foo
.
EDIT: the previous solution workis but is not robust since it depends on ordering the imports. That is not much ideal. Another solution (that occurred me after the first one) is to import the bar
module in foo.py
instead of only import the returnBar()
function:
from dirBar import bar
def printFoo():
print bar.returnBar()
This will work because the returnBar()
is now retrieved directly from the bar
module instead of the closure. So if I update the module, the new function will be retrieved.