hazrakah.mocks#

Provides Mock, Matcher argument matchers, a patch mechanism, and convenience functions.

Usage:

from hazrakah.mocks import Mock, 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.was_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 CallDetail(timestamp, took, is_async, parameters, result, error)#

Bases: object

Immutable record of a single mock call.

Variables:
  • 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.

  • parameters(args, kwargs) used to call the mock.

  • result – Return value from the call (None if no return value).

  • error – Exception raised by the call (None if none).

timestamp: float#
took: float#
is_async: bool#
parameters: tuple[tuple[Any, ...], dict[str, Any]]#
result: Any#
error: BaseException | None#
class Matcher#

Bases: object

Base class for argument matchers.

Subclasses must implement __eq__(self, other: Any) -> bool and return True when other matches the expected pattern. This allows Mock.was_called_with() to dispatch via Python’s equality operator naturally.

class Mock(origin=None, *, delegate=None, name='', validate=False, **kwargs)#

Bases: object

Lightweight mock object for dependency injection testing.

Every Mock instance can register itself as a virtual subclass of any type (ABC, @runtime_checkable Protocol, or concrete class) via the origin parameter – making isinstance(mock, origin) return True.

Usage:

from hazrakah.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.was_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.

  • validate (bool) – If True, validate call arguments against inspectable signatures.

  • kwargs (Any) – Arbitrary keyword arguments set as initial attribute values. Each key becomes an accessible attribute that returns the given value. The special key side_effect is 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 register method (for ABCs and runtime_checkable Protocols).

Parameters:

origin (type) – The type this mock stands in for.

Return type:

None

property origin: type | None#

The origin type this mock stands in for.

returns(value_or_callable)#

Set fixed return value or callable. Callable receives the mocked instance as its sole argument. Clears side_effect.

Return type:

Mock

side_effect(eff)#

Set side effect (callable/exception/iterable). Clears returns.

Return type:

Mock

was_called()#

Return True if this mock has been called at least once.

Return type:

bool

was_called_with(*args, **kwargs)#
Return type:

bool

Return True if any recorded call matches args and **kwargs.

Uses == dispatch for each argument, enabling matcher support.

reset()#

Clear call history; keep configuration intact.

Return type:

None

property call_count: int#

Number of calls recorded for this mock.

property calls: Sequence[CallDetail]#

Immutable sequence of all recorded calls.

exception MockError#

Bases: Exception

Exception raised when mock configuration is violated.

class neg(inner)#

Bases: Matcher

Wraps 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”.

Parameters:

inner (Matcher) – The matcher to negate.

Returns:

A Matcher instance.

property inner: Matcher#
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).

Parameters:

value (Any) – The value to search for.

Return type:

Matcher

Returns:

A Matcher instance.

is_any()#

Return a singleton matcher that matches any single value.

Return type:

Matcher

Returns:

A Matcher instance.

is_gte(n)#

Return a matcher that checks if the value is greater than or equal to n.

Parameters:

n (float) – The threshold to compare against.

Return type:

Matcher

Returns:

A Matcher instance.

is_gt(n)#

Return a matcher that checks if the value is strictly greater than n.

Parameters:

n (float) – The threshold to compare against.

Return type:

Matcher

Returns:

A Matcher instance.

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, while is_in(a, b, c) checks if the arg is one of a, b, or c.

Parameters:

values (Any) – The candidate values to check against.

Return type:

Matcher

Returns:

A Matcher instance.

is_lte(n)#

Return a matcher that checks if the value is less than or equal to n.

Parameters:

n (float) – The threshold to compare against.

Return type:

Matcher

Returns:

A Matcher instance.

is_lt(n)#

Return a matcher that checks if the value is strictly less than n.

Parameters:

n (float) – The threshold to compare against.

Return type:

Matcher

Returns:

A Matcher instance.

is_type(*types)#

Return a matcher that checks if the value is an instance of any given type(s).

Parameters:

types (type) – One or more types to check against.

Return type:

Matcher

Returns:

A Matcher instance.

class patch(target_path, origin=None, **kwargs)#

Bases: object

Patch 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(mock_connect):
    assert mock_connect.was_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.