Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock a function defined in a module of a package?

Tags:

python

mocking

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

like image 710
zalun Avatar asked Dec 20 '11 12:12

zalun


People also ask

How do you mock a function?

There are two ways to mock functions: Either by creating a mock function to use in test code, or writing a manual mock to override a module dependency.

How do you mock an NPM Jest module?

To mock a Node module with Jest, we can use the jest. createMockFromModule method. const utils = jest. createMockFromModule('../utils').

How do you mock a method in Jest?

The simplest and most common way of creating a mock is jest. fn() method. If no implementation is provided, it will return the undefined value. There is plenty of helpful methods on returned Jest mock to control its input, output and implementation.


2 Answers

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() 
like image 196
number5 Avatar answered Oct 10 '22 05:10

number5


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.

like image 39
brandizzi Avatar answered Oct 10 '22 05:10

brandizzi