mockify.mock - Classes for creating and inspecting mocks

Classes and functions used to create mocks.

Each of these can be considered as a frontend on top of mockify.core.Session class, which is acting as a sort of backend for mock classes.

class mockify.mock.BaseFunctionMock(name: str, session: ISession = None, parent: IMock = None)

Bases: BaseMock

Foundation class for making custom function mocks, with user-defined fixed set of positional and/or keyword arguments.

Each subclass must provide pair of expect_call and __call__ methods that will be used to record and consume (accordingly) expectations created with user-defined fixed set of arguments. Thanks to this class the linter will no longer complain about arguments that were redefined in subclass.

For easier subclassing, this class provides two helper methods for easier implementing of __call__ and expect_call methods:

Here’s an example:

from mockify.api import BaseFunctionMock, satisfied, Return

class DummyFunctionMock(BaseFunctionMock):

    def __call__(self, a, b, c=None):
        return self.__m_call__(a, b, c=c)

    def expect_call(self, a, b, c=None):
        return self.__m_expect_call__(a, b, c=c)

def call_func(func):
    return func(1, 2, c='spam')

def test_call_func():
    mock = DummyFunctionMock('mock')
    mock.expect_call(1, 2, c='spam').will_once(Return(123))
    with satisfied(mock):
        assert call_func(mock) == 123

Added in version 0.13.

__m_call__(*args, **kwargs)

A helper to implement __call__ method in a subclass.

__m_children__()

See mockify.abc.IMock.__m_children__().

__m_expect_call__(*args, **kwargs) IExpectation

A helper to implement expect_call method in a subclass.

__m_expectations__()

See mockify.abc.IMock.__m_expectations__()

class mockify.mock.BaseMock(name: str, session: ISession = None, parent: IMock = None)

Bases: IMock

Base class for all mock classes.

This class provides partial implementation of mockify.abc.IMock interface and common constructor used by all mocks. If you need to create custom mock, then it is better to inherit from this class at first place, as it provides some basic initialization out of the box.

Parameters:
  • name

    Name of this mock.

    This will be returned by __m_name__ property.

    See mockify.abc.IMock.__m_name__ for more information about naming mocks.

  • session

    Instance of mockify.abc.ISession to be used.

    If not given, parent’s session will be used (if parent exist) or a default mockify.core.Session session object will be created and used.

    Note

    This option is self-exclusive with parent parameter.

  • parent

    Instance of mockify.abc.IMock representing parent for this mock.

    When this parameter is given, mock implicitly uses paren’t session object.

    Note

    This option is self-exclusive with session parameter.

Changed in version 0.13: Moved from mockify.core into mockify.mock.

Changed in version 0.9: Added __init__ method, as it is basically same for all mock classes.

Added in version 0.8.

property __m_name__: str

See mockify.abc.IMock.__m_name__().

property __m_parent__: IMock | None

See mockify.abc.IMock.__m_parent__().

property __m_session__: ISession

See mockify.abc.IMock.__m_session__().

class mockify.mock.FunctionMock(name: str, session: ISession = None, parent: IMock = None)

Bases: BaseFunctionMock

Class for mocking arbitrary Python functions.

This is most basic mock class Mockify provides. You can use it to mock free Python functions (like callbacks), or to build more complex, custom mocks with it.

Here’s example usage:

from mockify.api import satisfied, Return, FunctionMock

def call_func(func):
    return func(1, 2, 3)

def test_call_func():
    func = FunctionMock('func')
    func.expect_call(1, 2, 3).will_once(Return(123))
    with satisfied(func):
        assert call_func(func) == 123

Changed in version 0.9: Removed parameter session in favour of **kwargs; session handling is now done by BaseMock class.

Added in version 0.8.

__call__(*args, **kwargs) Any | None

Call this mock.

expect_call(*args, **kwargs) IExpectation

Record call expectation on this mock.

class mockify.mock.Mock(name, max_depth=-1, **kwargs)

Bases: FunctionMock

General purpose mocking class.

This class can be used to:

  • create mocks of free functions (f.e. callbacks) or callable objects,

  • create mocks of any Python objects

  • create mocks of namespaced function calls (f.e. foo.bar.baz.spam(...)),

  • create ad-hoc data objects.

No matter what you will be mocking, for all cases creating mock objects is always the same - by giving it a name and optionally session. Mock objects automatically create attributes on demand, and that attributes form some kind of nested or child mocks.

To record expectations, you have to call expect_call() method on one of that attributes, or on mock object itself (for function mocks). Then you pass mock object to unit under test. Finally, you will need mockify.core.assert_satisfied() function or mockify.core.satisfied() context manager to check if the mock is satisfied.

Currently supported magic methods are:

  • Comparison operators:

    • __eq__(self, other), i.e. ==

    • __ne__(self, other), i.e. !=

    • __lt__(self, other), i.e. <

    • __gt__(self, other), i.e. >

    • __le__(self, other), i.e. <=

    • __ge__(self, other), i.e. >=

  • Unary arithmethic operators:

    • __pos__(self), f.e. +foo

    • __neg__(self), f.e. -foo

    • __abs__(self), f.e. abs(foo)

    • __invert__(self), f.e. ~foo

    • __round__(self, ndigits=None), f.e. round(foo) or round(foo, ndigits)

    • __floor__(self), f.e. floor(foo)

    • __ceil__(self), f.e. ceil(foo)

  • Normal arithmethic operators, including reflected versions for all

    listed below (f.e. __radd__ for __add__, which will be called in other + foo statement, as opposed to typical foo + other):

    • __add__(self, other)__, f.e. foo + other

    • __sub__(self, other)__, f.e. foo - other

    • __mul__(self, other)__, f.e. foo * other

    • __floordiv__(self, other)__, f.e. foo // other

    • __div__ and __truediv__, f.e. foo / other

    • __mod__(self, other)__, f.e. foo % other

    • __divmod__(self, other)__, f.e. divmod(foo, other)

    • __pow__(self, other)__, f.e. foo ** other

    • __lshift__(self, other), f.e. foo << other

    • __rshift__(self, other), f.e. foo >> other

    • __and__(self, other), f.e. foo & other

    • __or__(self, other), f.e. foo | other

    • __xor__(self, other), f.e. foo ^ other

  • In-place arithmethic operators:

    • __iadd__(self, other)__, f.e. foo += other

    • __isub__(self, other)__, f.e. foo -= other

    • __imul__(self, other)__, f.e. foo *= other

    • __ifloordiv__(self, other)__, f.e. foo //= other

    • __idiv__ and __itruediv__, f.e. foo /= other

    • __imod__(self, other)__, f.e. foo %= other

    • __ipow__(self, other)__, f.e. foo **= other

    • __ilshift__(self, other), f.e. foo <<= other

    • __irshift__(self, other), f.e. foo >>= other

    • __iand__(self, other), f.e. foo &= other

    • __ior__(self, other), f.e. foo |= other

    • __ixor__(self, other), f.e. foo ^= other

  • Type conversion operators:

    • __str__(self), f.e. str(foo)

    • __int__(self), f.e. int(foo)

    • __float__(self), f.e. float(foo)

    • __complex__(self), f.e. complex(foo)

    • __index__(self), f.e. oct(foo), hex(foo) or when used

      in slice expression

  • Class representation methods:

    • __repr__(self), f.e. repr(foo)

    • __format__(self, formatstr), used when str.format() is

      given an instance of a mock (formatstr is then passed from formatting options, f.e. "{:abc}".format(foo) will pass abc as formatstr)

    • __hash__(self), called by built-in hash()

    • __dir__(self), called by built-in dir()

    • __sizeof__(self), called by sys.getsizeof()

  • Attribute access methods:

    • __getattr__(self, name), used by getattr() or when

      attribute is being get (f.e. spam = foo.spam)

    • __setattr__(self, name, value), used by setattr() or

      when attribute is being set (f.e. foo.spam = 123)

    • __delattr__(self, name), used by delattr() or when

      when attrbute is being deleted (f.e. del foo.spam)

    Note

    If the methods above are not mocked, default implementations will be used, allowing to set/get/delete a user-defined attributes:

    >>> foo = Mock('foo')
    >>> foo.spam = 123
    >>> foo.spam
    123
    >>> del foo.spam
    

    However, if explicit expectation is set, the behaviour from above will be replaced with calling adequate mock object:

    foo = Mock('foo')
    foo.__getattr__.expect_call('spam').will_once(Return(123))
    with satisfied(foo):
        assert foo.spam == 123
    
  • Container methods:

    • __len__(self), called by len()

    • __getitem__(self, key), called when item is being get (f.e.

      spam = foo['spam'])

    • __setitem__(self, key, value), called when item is being set

      (f.e. foo['spam'] = 123)

    • __delitem__(self, key), called when item is being deleted

      (f.e. del foo['spam'])

    • __reversed__(self), called by reversed()

    • __contains__(self, key), called when mock is tested for

      presence of given item (f.e. if 'spam' in foo:)

  • Generator methods:

    • __iter__(self), called by iter() or when iterating over

      mock object

    • __next__(self), called by next()

    • __aiter__(self), called when asynchronous generator is

      created, f.e. used by async for statement

    • __anext__(self), called to advance an asynchronous generator

  • __call__ method:

    • __call__(self, *args, **kwargs)

    Note

    Recording expectation explicitly on object.__call__() magic method is equivalent to recording call expectation directly on a mock object:

    foo = Mock('foo')
    foo.__call__.expect_call('one').will_once(Return(1))
    foo.expect_call('two').will_once(Return(2))
    with satisfied(foo):
        assert foo('one') == 1
        assert foo('two') == 2
    
  • Context management methods:

    • __enter__(self)

    • __aenter__(self)

    • __exit__(self, exc, exc_type, tb)

    • __aexit__(self, exc, exc_type, tb)

  • Descriptor methods:

    • __get__(self, obj, obj_type)

    • __set__(self, obj, value)

    • __delete__(self, obj)

Here’s an example:

from mockify.core import satisfied
from mockify.mock import Mock

def caller(func, a, b):
    func(a + b)

def test_caller():
    func = Mock('func')
    func.expect_call(5)
    with satisfied(func):
        caller(func, 2, 3)

See Creating mocks and recording expectations for more details.

Changed in version 0.13: Changelog:

  • Now Mock inherits from mockify.mock.FunctionMock to avoid code duplication

  • Added max_depth parameter

  • Added support for (almost) all magic methods

Changed in version 0.8: Now this class inherits from mockify.mock.BaseMock

Added in version 0.6.

__m_children__()

See mockify.abc.IMock.__m_children__().

expect_call(*args, **kwargs)

Record call expectation on this mock.

class mockify.mock.MockFactory(name=None, mock_class=None, **kwargs)

Bases: BaseMock

A factory class used to create groups of related mocks.

This class allows to create mocks using class given by mock_class ensuring that:

  • names of created mocks are unique,

  • all mocks share one common session object.

Instances of this class keep track of created mocks. Moreover, functions that would accept Mock instances will also accept MockFactory instances, so you can later f.e. check if all created mocks are satisfied using just a factory object. That makes it easy to manage multiple mocks in large test suites.

See Managing multiple mocks for more details.

Changed in version 0.8: Now it inherits from mockify.mock.BaseMock, as this class is more or less special kind of mock.

Added in version 0.6.

Parameters:
  • name

    This is optional.

    Name of this factory to be used as a common prefix for all created mocks and nested factories.

  • mock_class

    The class that will be used by this factory to create mocks.

    By default it will use Mock class.

Changed in version 0.9: Removed parameter session in favour of **kwargs; session handling is now done by BaseMock class.

__m_children__()

An iterator over IMock objects representing direct children of this mock.

This SHOULD NOT include grandchildren.

__m_expectations__()

An iterator over IExpectation objects recorded for this mock.

This SHOULD NOT include expectations recorded for children of this mock.

factory(name)

Create and return child factory.

Child factory will use session from its parent, and will prefix all mocks and grandchild factories with given name.

This method will raise TypeError if name is already used by either mock or child factory.

Return type:

MockFactory

mock(name)

Create and return mock of given name.

This method will raise TypeError if name is already used by either mock or child factory.

mockify.mock.ABCMock(name, abstract_base_class, **kwargs)

Factory function for creating mocks that implement given abc.ABC subclass.

This class is meant to be used with interfaces containing abstract methods. It performs a lookup on the interface and allows to record expectations only on methods that are defined in the interface. Moreover, it also checks argument names and disallow recording calls with invalid arguments; everything must match the definition of the interface.

Here’s an example:

import abc

from mockify.core import satisfied
from mockify.mock import ABCMock
from mockify.actions import Return

class Interface(abc.ABC):

    @abc.abstractmethod
    def method(self, a, b):
        pass

mock = ABCMock('mock', Interface)
mock.method.expect_call(1, 2).will_once(Return(123))
with satisfied(mock):
    assert mock.method(1, 2) == 123
Parameters:
  • name – Mock name

  • abstract_base_class – Subclass of abc.ABC to be used as source of abstract methods that will be implemented by this mock.

Changed in version 0.9: * Now this is a factory function returning mock object * Parameter session is removed in favour of **kwargs; session is now handled by BaseMock class

Added in version 0.8.