Testing
micro.override(*components)
Swaps components inside an active async with micro: block.
from unittest.mock import AsyncMock
from grelmicro import Grelmicro
from grelmicro.sync import Sync
from grelmicro.sync.abc import SyncBackend
async def test_swap_for_block(micro: Grelmicro) -> None:
fake_backend = AsyncMock(spec=SyncBackend)
async with micro:
async with micro.override(Sync(fake_backend)):
await do_something_that_uses_sync()
fake_backend.acquire.assert_awaited()
Override components are entered when the block opens and exited in reverse order when it closes. Prior registrations are restored on exit, including when the block raises.
Restrictions
- Only
Componentinstances can be overridden. Plain async context managers passed touse(...)are substituted at construction time, not throughoverride(). - Calling
micro.override(...)outside an activeasync with micro:raisesOutOfContextError.
Pytest recipe
grelmicro ships no pytest plugin. Add a micro fixture in conftest.py:
from collections.abc import AsyncIterator
import pytest
from grelmicro import Grelmicro
from grelmicro.cache import Cache
from grelmicro.cache.memory import MemoryCacheAdapter
from grelmicro.sync import Sync
from grelmicro.sync.memory import MemorySyncAdapter
@pytest.fixture
async def micro() -> AsyncIterator[Grelmicro]:
app = Grelmicro(uses=[
Sync(MemorySyncAdapter()),
Cache(MemoryCacheAdapter()),
])
async with app:
yield app
Tests then read micro as a fixture and apply per-case overrides:
from unittest.mock import AsyncMock
from grelmicro import Grelmicro
from grelmicro.sync import Sync
from grelmicro.sync.abc import SyncBackend
async def test_login(micro: Grelmicro) -> None:
fake_backend = AsyncMock(spec=SyncBackend)
async with micro.override(Sync(fake_backend)):
await do_login("u1")