Skip to content

Latest commit

 

History

History
85 lines (65 loc) · 1.93 KB

README.md

File metadata and controls

85 lines (65 loc) · 1.93 KB

mock_protocol

A unittest mock library than understands protocols and annotations

A drop-in replacement for the builtin python 3.7 unittest.mock module where annotations on spec objects are used to spec mocked attributes and methods.

In addition to the standard unittest.mock functionality, a new from_protocol function is added.

import mock_protocol

m = mock_protocol.from_protocol(C, **kwargs)

is an alias for

m = mock_protocol.create_autospec(C, spec_set=True, instance=True, **kwargs)

which is essentially the same as the unittest.mock method of the same name

m = unittest.mock.create_autospec(C, spec_set=True, instance=True, **kwargs)

except that type-hints are used to spec the mocked attributes.

When you have type-hinted code like this

class A(object):
    b: str

    def __init__(self, b: str):
        self.b = b

    def foo(self, bar: int) -> list:
        return ['x']*bar


class C(object):
    a: int

    def __init__(self, a: int):
        self.a = a

    def bar(self, foo: str) -> A:
        return A(foo)

Then mocking them with mock_protocol will use the type hints as specs for child mocks.

m = mock_protocol.from_protocol(C)
a = m.bar('hello')

# the following are all True
isinstance(a, A)
isinstance(a.b, str)
isinstance(m.a, int)
isinstance(a.foo(4), list)

mock_protocol also understands common typing types such as Dict and Tuple and Optional

import typing

class D(object):
    a: typing.Optional[int]
    d: typing.Dict[str, int]
    e: typing.Optional[typing.AnyStr]
    t: typing.Tuple[int, float]

    def __init__(self, a: int):
        self.a = a

    def bar(self, foo: str) -> typing.Optional[A]:
        return A(foo)

m = mock_protocol.from_protocol(D)
a = m.bar('hello')

# the following are all True
isinstance(m, D)
isinstance(a, A)
isinstance(m.a, int)
isinstance(m.d, dict)
isinstance(m.e, str)
isinstance(m.t, tuple)