Skip to main content

Testing utility decorators for mocking functions, variables, and HTTP endpoints

Project description

pymocks

Testing utility decorators for mocking functions, variables, and HTTP endpoints in Python.

Works with both synchronous and asynchronous test functions. Sync/async is detected automatically.

Installation

pip install pymocks

Or with uv:

uv add pymocks

Usage

Mocking Functions and Variables

Use Mock with @with_mock to monkeypatch a module attribute for the duration of a test:

import my_module
from pymocks import Mock, with_mock


# Mock a function — the replacement must have the same signature
def fake_function(x: int, y: str) -> bool:
    return True


mock = Mock(
    module_where_used=my_module,
    current_value=my_module.some_function,
    new_value=fake_function,
)


@with_mock(mock)
def test_with_mocked_function():
    result = my_module.some_function(1, "a")
    assert result is True


# Mock a variable — the replacement must have the same type
var_mock = Mock(
    module_where_used=my_module,
    current_value=my_module.API_URL,
    new_value="https://mock.example.com",
)


@with_mock(var_mock)
def test_with_mocked_variable():
    assert my_module.API_URL == "https://mock.example.com"

The same decorator works for async tests:

@with_mock(mock)
async def test_async_with_mock():
    result = my_module.some_function(1, "a")
    assert result is True

Mocking Classes

Use Mock to replace a class with a subclass. The replacement must be a subclass of the original:

import my_module
from pymocks import Mock, with_mock


class FakeService(my_module.Service):
    def fetch(self) -> str:
        return "fake data"


mock = Mock(
    module_where_used=my_module,
    current_value=my_module.Service,
    new_value=FakeService,
)


@with_mock(mock)
def test_with_mocked_class():
    svc = my_module.Service()
    assert svc.fetch() == "fake data"

Replacing a class with an unrelated class raises TypeError:

class Unrelated:
    pass


# Raises TypeError — Unrelated is not a subclass of Service
Mock(
    module_where_used=my_module,
    current_value=my_module.Service,
    new_value=Unrelated,
)

Signature and Type Validation

Mock validates compatibility between current_value and new_value at construction time:

  • Callables: signatures must match exactly (parameter count, names, kinds, annotations, and return annotation)
  • Classes: new_value must be a subclass of current_value
  • Non-callables: type(current_value) must be the same as type(new_value)
  • Mixed: replacing a callable with a non-callable (or vice versa) raises TypeError
def original(x: int) -> str:
    return str(x)


# Signature mismatch — raises TypeError immediately
Mock(
    module_where_used=my_module,
    current_value=original,
    new_value=lambda x: str(x),  # missing annotations
)

# Type mismatch — raises TypeError immediately
Mock(
    module_where_used=my_module,
    current_value="a string",
    new_value=42,
)

Mocking HTTP Endpoints

Use MockEndpoint with @with_endpoints to mock HTTP calls via aioresponses:

import aiohttp
from pymocks import MockEndpoint, with_endpoints

endpoints = (
    MockEndpoint(
        url="https://api.example.com/users",
        method="GET",
        json_response={"users": [{"id": 1, "name": "Alice"}]},
    ),
    MockEndpoint(
        url="https://api.example.com/users",
        method="POST",
        json_response={"id": 2, "name": "Bob"},
    ),
)


@with_endpoints(endpoints)
async def test_api_calls():
    async with aiohttp.ClientSession() as session:
        async with session.get("https://api.example.com/users") as resp:
            data = await resp.json()
            assert len(data["users"]) == 1

API Reference

Mock[T_mocked]

A dataclass that defines a monkeypatch specification. Validates compatibility on construction.

Field Type Description
module_where_used ModuleType The module containing the attribute to patch
current_value T_mocked The current value (used to find its name)
new_value T_mocked The replacement value during the test

MockEndpoint

A frozen dataclass defining an HTTP endpoint mock.

Field Type Description
url str The URL to mock
method Literal["GET", "POST", "PUT", "DELETE"] HTTP method
json_response dict[str, JsonValue] | None JSON response body (optional)
body str | None Raw string body (optional)

Decorators

Decorator Description
@with_mock(mock) Monkeypatches a module attribute during a test
@with_endpoints(endpoints) Mocks HTTP endpoints during a test via aioresponses

Both decorators auto-detect sync/async and wrap accordingly.

Requirements

  • Python >= 3.12
  • pytest
  • aioresponses

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

py_mocks-0.1.0.tar.gz (51.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

py_mocks-0.1.0-py3-none-any.whl (5.8 kB view details)

Uploaded Python 3

File details

Details for the file py_mocks-0.1.0.tar.gz.

File metadata

  • Download URL: py_mocks-0.1.0.tar.gz
  • Upload date:
  • Size: 51.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.1 {"installer":{"name":"uv","version":"0.11.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for py_mocks-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d2910e62b202125bff346713a5bd2ae0587b9109103a7e6151038c26c6636531
MD5 6777d553acbfd677214d6f371d10a8ec
BLAKE2b-256 ecf92bbbbec35d5e0613742fdaaa39a83e70c4189ff8a6ef0c232a1756920fa3

See more details on using hashes here.

File details

Details for the file py_mocks-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: py_mocks-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 5.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.1 {"installer":{"name":"uv","version":"0.11.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for py_mocks-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f02a3c0a69f9b2142742cc04b6c3cc5e397f7eb99f9958c284a746579ba58d09
MD5 ebb5d41d6f258986f99b5371ba2cd1a1
BLAKE2b-256 2fd885c93222f61e1dc6e1a018bc6120d7a85d7dcf876bd0f969ace37a2b2c05

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page