punit.mocks#
Provides mocking facilities via a m:class:Mock class and/or a m:class:patch class.
Usage:
from punit.mocks import Mock, is_any, contains, patch
# Fluent syntax
mock = (
Mock()
.do_stuff.returns(42)
)
# Constructor kwargs for fixture-style initialization
user = Mock(first_name='Alice', email='alice@example.com')
assert user.first_name == 'Alice'
assert user.email == 'alice@example.com'
# Matcher-based verification
assert mock.called_with(
is_any(),
neg(contains('foo')),
is_in(1, 2, 3))
# Module-level patching
with patch('some.module.ClassName') as m:
m.method.returns('result')
- class Call(*args: Any, **kwargs: Any)#
Bases:
objectImmutable record of a single mock call.
Call records carry the full metadata set (timestamp, took, is_async, result, error) so that
.callsand.mock_callsreturn semantically identical data.- Variables:
path – Absolute dotted path name (e.g.
'Mock.foo.bar').timestamp – Time when the call occurred (
time.monotonic_ns()).took – Time spent in the call, in seconds.
is_async – Whether the call was made via
await.args – Positional arguments passed to the mock.
kwargs – Keyword arguments passed to the mock.
result – Return value from the call (
Noneif no return value).error – Exception raised by the call (
Noneif none).
Examples:
>>> Call('Mock.foo', (1,), {'key': 'val'}) >>> Call(path='Mock.foo', timestamp=42.0, took=0.001, is_async=False, args=(1,), kwargs={'key': 'val'}, result='r', error=None)
- path: str = ''#
- timestamp: float = 0.0#
- took: float = 0.0#
- is_async: bool = False#
- args: tuple[Any, ...] = ()#
- kwargs: dict[str, Any]#
- result: Any = None#
- error: BaseException | None = None#
- class CallList(iterable=(), /)#
Bases:
tupleTuple of
Callsupporting partial-sublist matching via__contains__.
- class Matcher#
Bases:
ABCBase class for argument matchers.
Subclasses must implement
__eq__(self, other: Any) -> booland returnTruewhen other matches the expected pattern. This allowsMock.called_with()to dispatch via Python’s equality operator naturally.
- class Mock(origin=None, *, delegate=None, name='Mock', returns=None, **kwargs)#
Bases:
objectLightweight mock object for dependency injection testing.
Every
Mockinstance can register itself as a virtual subclass of any type (ABC,@runtime_checkableProtocol, or concrete class) via the origin parameter – makingisinstance(mock, origin)returnTrue.Usage:
from punit.mocks import Mock # Create a mock that conforms to UserService structurally mock = Mock(origin=UserService) mock.is_authenticated.returns(False) mock.get_user.returns('Guest') assert mock.called_with(42)
Child mocks (returned by attribute access) are cached –
mock.foo is mock.foo.Create a new Mock instance.
- Parameters:
origin (
Optional[type]) – The type this mock stands in for (enables isinstance checks).delegate (
Any) – A real object whose methods are forwarded when not configured.name (
str) – Debug identifier for the mock. Defaults to'Mock'.validate – If True, validate call arguments against inspectable signatures.
returns (
Any) – A convenience kwarg that assigns a return value for the Mock, similar to calling returns(…).kwargs (
Any) – Arbitrary keyword arguments set as initial attribute values. Each key becomes an accessible attribute that returns the given value. The special keyside_effectis applied to this mock’s calling behavior.
- classmethod register_origin(origin)#
Register origin so that Mock instances pass
isinstance(_, origin).Dispatches to the origin’s
registermethod (for ABCs and runtime_checkable Protocols).- Parameters:
origin (
type) – The type this mock stands in for.- Return type:
None
- property call_count: int#
Number of calls recorded for this mock.
- property called: bool#
Return True if this mock has been called (self-invocations.)
- property child_calls: CallList#
Calls reached through child attribute access only (not self-invocations.)
- property origin: type | None#
The origin type this mock stands in for.
- property side_effect: Callable[[Callable[[...], Any] | BaseException | type | Iterable[Any] | None], Mock]#
Set side effect (callable/exception/iterable). Clears returns.
- when(*args, **kwargs)#
Create a conditionally-dispatched subgraph mock keyed by matcher arguments.
Identical matcher tuples always return the same subgraph (dedup via canonical name). The matched subgraph’s
__call__is forwarded matching call args for dispatch to further nested conditions or flat config.
- returns(value_or_callable)#
Set fixed return value or callable. Callable receives the mocked instance as its sole argument. Clears side_effect.
- Return type:
- reset(*, preserve_stubs=True, preserve_sideeffects=True)#
Reset this mock’s call tracking and optionally its configuration.
- Parameters:
preserve_stubs (
bool) – IfTrue(default), retain child stubs created by attribute access or from an origin. IfFalse, recursively clear all children so that subsequent attribute access creates fresh mocks.preserve_sideeffects (
bool) – IfTrue(default), keep fluent-configuration values such as__return_value__and__side_effect__intact. IfFalse, wipe all__*-prefixed* configuration keys from ``_u.configuredand reset the has_* flags, but leave structural stubs (origin-prepopulated members) untouched.
- Return type:
None
- exception MockError#
Bases:
ExceptionException raised when mock configuration is violated.
- class neg(inner)#
Bases:
MatcherWraps another matcher and negates its result.
This enables composing matchers freely – e.g.
neg(is_in('admin', 'root'))matches any value that is not ‘admin’ or ‘root’.
- contains(value)#
Return a matcher that checks if value is a substring of a string or an element of a container (list, tuple, set, dict keys).
- is_any()#
Return a singleton matcher that matches any single value.
- is_gte(n)#
Return a matcher that checks if the value is greater than or equal to n.
- is_gt(n)#
Return a matcher that checks if the value is strictly greater than n.
- is_in(*values)#
Return a matcher that checks if the value equals one of the provided values.
This is the inverse of
contains()–contains(x)checks if x is in the arg, whileis_in(a, b, c)checks if the arg is one of a, b, or c.
- is_lte(n)#
Return a matcher that checks if the value is less than or equal to n.
- is_lt(n)#
Return a matcher that checks if the value is strictly less than n.
- is_type(*types)#
Return a matcher that checks if the value is an instance of any given type(s).
- class patch(target_path, origin=None, **kwargs)#
Bases:
objectPatch a module-level attribute with a
Mock.Can be used as both a context manager and a decorator. The same instance handles both via
__enter__/__exit__and__call__.Usage:
# As context manager: with patch('myapp.db.connect') as mock_connect: mock_connect.returns('connected') # As decorator: @patch('myapp.db.connect') def test_something(m): assert m.called
Create a new patch for the given dotted path.
- Parameters:
target_path (
str) – Dotted attribute path to replace (e.g.'myapp.database.connect').origin (
Optional[type]) – Optional type for Mock virtual-subclass registration.kwargs (
Any) – Additional keyword arguments forwarded to the Mock constructor.