# encoding: utf-8 """ Utility functions wrapping the excellent *mock* library. """ from __future__ import absolute_import, print_function import sys if sys.version_info >= (3, 3): from unittest import mock # noqa from unittest.mock import call, MagicMock # noqa from unittest.mock import create_autospec, Mock, patch, PropertyMock else: import mock # noqa from mock import ANY, call, MagicMock # noqa from mock import create_autospec, Mock, patch, PropertyMock def class_mock(request, q_class_name, autospec=True, **kwargs): """ Return a mock patching the class with qualified name *q_class_name*. The mock is autospec'ed based on the patched class unless the optional argument *autospec* is set to False. Any other keyword arguments are passed through to Mock(). Patch is reversed after calling test returns. """ _patch = patch(q_class_name, autospec=autospec, **kwargs) request.addfinalizer(_patch.stop) return _patch.start() def cls_attr_mock(request, cls, attr_name, name=None, **kwargs): """ Return a mock for attribute *attr_name* on *cls* where the patch is reversed after pytest uses it. """ name = request.fixturename if name is None else name _patch = patch.object(cls, attr_name, name=name, **kwargs) request.addfinalizer(_patch.stop) return _patch.start() def function_mock(request, q_function_name, **kwargs): """ Return a mock patching the function with qualified name *q_function_name*. Patch is reversed after calling test returns. """ _patch = patch(q_function_name, **kwargs) request.addfinalizer(_patch.stop) return _patch.start() def initializer_mock(request, cls): """ Return a mock for the __init__ method on *cls* where the patch is reversed after pytest uses it. """ _patch = patch.object(cls, '__init__', return_value=None) request.addfinalizer(_patch.stop) return _patch.start() def instance_mock(request, cls, name=None, spec_set=True, **kwargs): """ Return a mock for an instance of *cls* that draws its spec from the class and does not allow new attributes to be set on the instance. If *name* is missing or |None|, the name of the returned |Mock| instance is set to *request.fixturename*. Additional keyword arguments are passed through to the Mock() call that creates the mock. """ name = name if name is not None else request.fixturename return create_autospec( cls, _name=name, spec_set=spec_set, instance=True, **kwargs ) def loose_mock(request, name=None, **kwargs): """ Return a "loose" mock, meaning it has no spec to constrain calls on it. Additional keyword arguments are passed through to Mock(). If called without a name, it is assigned the name of the fixture. """ if name is None: name = request.fixturename return Mock(name=name, **kwargs) def method_mock(request, cls, method_name, **kwargs): """ Return a mock for method *method_name* on *cls* where the patch is reversed after pytest uses it. """ _patch = patch.object(cls, method_name, **kwargs) request.addfinalizer(_patch.stop) return _patch.start() def property_mock(request, cls, prop_name, **kwargs): """ Return a mock for property *prop_name* on class *cls* where the patch is reversed after pytest uses it. """ _patch = patch.object(cls, prop_name, new_callable=PropertyMock, **kwargs) request.addfinalizer(_patch.stop) return _patch.start() def var_mock(request, q_var_name, **kwargs): """ Return a mock patching the variable with qualified name *q_var_name*. Patch is reversed after calling test returns. """ _patch = patch(q_var_name, **kwargs) request.addfinalizer(_patch.stop) return _patch.start()