A decorator for easily mocking out multiple dependencies by monkey-patching.
Project description
A decorator for easily mocking out multiple dependencies by monkey-patching.
simian.patch is a wrapper around mock.patch to allow for convenient patching of multiple targets in a single decorator. All resulting patched objects are collected under a single master_mock object, which is provided to the function being decorated.
For example:
#
# my_package.my_module
#
from time import sleep
def my_sleep(duration_secs):
print('Sleeping for {duration} seconds'.format(duration=duration_secs))
sleep(duration_secs)
#
# my_package.test.test_my_module
#
import simian
from my_package import my_module
@simian.patch(my_module, external=['time.sleep'])
def test_my_sleep(master_mock):
my_module.my_sleep(99)
master_mock.sleep.assert_called_once_with(99)
Note several things about time.sleep in the above example:
It is patched and provided to the test as master_mock.sleep.
The patching works despite my_sleep calling sleep directly, as opposed to calling the fully-qualified time.sleep.
The second point works because simian.patch reloads the given module after patching all of the external targets. It reloads the module again after leaving the decorated function, bringing the module back to its pre-patched state.
The above example demonstrates external patching, but internal (same-module) patching works as well. Let’s extend the above example:
#
# my_package.my_module
#
from time import sleep
def my_sleep(duration_secs):
my_logger('Starting {n}-second sleep'.format(n=duration_secs))
sleep(duration_secs)
my_logger('Finished {n}-second sleep'.format(n=duration_secs))
def my_logger(msg):
...
#
# my_package.test.test_my_module
#
import simian
from my_package import my_module
@simian.patch(
my_module,
'my_package.my_module',
external=['time.sleep'],
internal=['my_logger'])
def test_my_sleep(master_mock):
my_module.my_sleep(99)
master_mock.assert_has_calls(
calls=[
call.my_logger('Starting 99-second sleep'),
call.sleep(99),
call.my_logger('Finished 99-second sleep')],
any_order=False)
Note that when internal targets are supplied, the full path to the module under test must also be supplied (in this case, my_package.my_module).
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.