Skip to main content

A decorator for easily mocking out multiple dependencies by monkey-patching.

Project description

Compatibility Implementations Format Downloads

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.

Source Distribution

simian-1.0.5.tar.gz (3.3 kB view hashes)

Uploaded Source

Built Distribution

simian-1.0.5-py2.py3-none-any.whl (3.7 kB view hashes)

Uploaded Python 2 Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page