Quickstart

There are four ways to drive the mock lifecycle. Pick whichever fits your test framework.

Context manager

import aiohttp
from aiointercept import aiointercept

async def test_get_user():
    async with aiointercept() as m:
        m.get(f"{m.server_url}/user/1", payload={"id": 1, "name": "Alice"})

        async with aiohttp.ClientSession() as session:
            resp = await session.get(f"{m.server_url}/user/1")
            assert resp.status == 200
            assert await resp.json() == {"id": 1, "name": "Alice"}

Decorator

The aiointercept instance is injected as the last positional argument, or under the name given by param:

from aiointercept import aiointercept

@aiointercept()
async def test_create_post(m):
    m.post(f"{m.server_url}/posts", status=201, payload={"id": 42})
    ...

@aiointercept(param="mock")
async def test_named(mock):
    mock.get(f"{mock.server_url}/feed", payload=[])
    ...

pytest fixture

import pytest_asyncio
from aiointercept import aiointercept

@pytest_asyncio.fixture
async def mock_http():
    async with aiointercept() as m:
        yield m

async def test_something(mock_http):
    mock_http.get(f"{mock_http.server_url}/items", payload=[{"id": 1}])
    ...

Note

@pytest_asyncio.fixture works in all pytest-asyncio modes. If you use asyncio_mode = "auto" in pyproject.toml, a plain @pytest.fixture works too.

Manual start() / stop()

For frameworks with their own setup/teardown hooks (e.g. unittest.IsolatedAsyncioTestCase) you can drive the lifecycle explicitly:

import unittest
from aiointercept import aiointercept

class TestApi(unittest.IsolatedAsyncioTestCase):
    async def asyncSetUp(self):
        self.helper = aiointercept()
        await self.helper.start()

    async def asyncTearDown(self):
        await self.helper.stop()

    async def test_user(self):
        self.helper.get(f"{self.helper.server_url}/user/1", payload={"id": 1})
        ...

Sharing the server across tests

Each async with aiointercept() block starts a fresh aiohttp.web test server. The bundled pytest plugin (auto-discovered, requires pytest-asyncio) amortizes that with a session-scoped server and a function-scoped wrapper that calls clear() between tests.

async def test_get_user(aiointercept_mock):
    m = aiointercept_mock
    m.get(f"{m.server_url}/user/1", payload={"id": 1, "name": "Alice"})

    async with aiohttp.ClientSession() as session:
        resp = await session.get(f"{m.server_url}/user/1")
        assert resp.status == 200
    m.assert_called_with(f"{m.server_url}/user/1", method="GET")

Fixtures: aiointercept_server (session) and aiointercept_mock (function — use this in tests). Override aiointercept_server in your conftest.py to customize.

Note

The plugin defaults to mock_external_urls=False. To intercept URLs for the whole session, override aiointercept_server and pass mock_external_urls=True — note that the DNS/SSL patches are installed at the class level and stay live for every aiohttp call in the test process (this blocks real network calls).