LANGUAGE » PYTHON » PACKAGE
Mock
Usage
Import from unittest.mock
, or from mock
if installed separately.
Set value
python
@mock.patch('calc.Calculator.sum')
def test_sum_return_value(self, sum):
sum.return_value = 9
Side effect
python
def sum(a, b):
if a > b:
return 5
return 10
@mock.patch('mymodule.sum')
def test_sum_side_effect(self, mock_sum):
mock_sum.side_effect = sum
@mock.patch('mymodule.sum', side_effect=Exception())
def test_sum_side_effect(self, mock_sum):
mymodule.sum() # Will raise Exception()
Assert call
python
@mock.patch('calc.Calculator.sum')
def test_call_count(self, sum):
sum.assert_called_with(1) # Asserts the last call's parameters
sum.assert_any_call(1) # Asserts any call's parameters
assert sum.call_count == 3
sum.call_args
sum.call_args_list
Mock file
python
def test_open_file(self):
mock_open = mock.mock_open(read_data='file_content')
with mock.patch('builtins.open', mock_open):
with open('/some/path', 'r') as text_file:
text_file.read() # Returns 'file_content'
mock_open.assert_any_call('/some/path', 'r')
mock_open().write.call_args.args
Mock module
python
import sys
sys.modules['some_module'] = mock.MagicMock()
Tips
Mocking can sometimes be tricky. Understanding how it works can help saving some time.
Mock your own module
Mock your own module instead the original module. Let's say your module is at a.b
and it imports x.y.z
. You want to mock z
.
The result of mocking may be like this:
python
@mock.patch('x.y.z') # Does not work...
@mock.patch('a.b.z') # Works!
Reloading the module
Mocking a module that is already loaded won't work. This often happens when you load a module in a import
statement at the top of the script, and create a mock for it in runtime.
To solve this, reload the module after creating the mock:
python
from importlib import reload # Python >= 3.4 only, else unneeded
reload(x.y.z)