pytest

Built-in pytest plugin (Injected parameters)

diwire ships with an optional pytest plugin that resolves parameters annotated as Injected[T] from a container.

Enable it in a test module or conftest.py:

pytest_plugins = ["diwire.integrations.pytest_plugin"]

Then annotate parameters:

from diwire import Injected


def test_example(service: Injected["Service"]) -> None:
    assert service is not None

Customizing the container

The plugin uses a diwire_container fixture. Override it to register fakes and test-specific configuration. Injected parameters are always resolved from this root container.

import pytest

from diwire import Container, Lifetime


@pytest.fixture()
def diwire_container() -> Container:
    container = Container()
    container.add(FakeService, provides=Service,
        lifetime=Lifetime.SCOPED,
    )
    return container

Notes

  • The plugin removes injected parameters from pytest’s fixture signature so normal fixture discovery still works.

  • The plugin is loaded via pytest_plugins; it is not auto-registered.

Container fixture

import pytest

from diwire import Container


@pytest.fixture
def container() -> Container:
    # Prefer a fresh container per test.
    return Container()

Using resolver_context in tests

If your app uses diwire.resolver_context, prefer explicit resolver injection in tests. This avoids ambient resolver state leaks between tests.

import pytest

from diwire import Container, Injected, resolver_context


@pytest.fixture
def container() -> Container:
    container = Container()
    container.add_instance(Service(), provides=Service)
    return container


@resolver_context.inject
def build_service(service: Injected[Service]) -> Service:
    return service


def test_build_service(container: Container) -> None:
    assert build_service(diwire_resolver=container.compile()) is not None

Cleaning up scopes

Prefer with container.enter_scope(...): in tests so scope cleanup is deterministic. If you create scopes imperatively, close them (or call diwire.Container.close()) in teardown.