Skip to content

Latest commit

Β 

History

70 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

modern-di-pytest

PyPI version Supported Python versions Downloads Coverage CI License GitHub stars uv Ruff ty

Pytest integration for modern-di. It turns any DI dependency into a pytest fixture with one line.

Full guide: pytest integration docs

Installation

uv add --dev modern-di-pytest      # or: pip install modern-di-pytest

Usage

You provide the root container fixture. Pick whatever pytest scope fits the test suite:

# conftest.py
import typing

import modern_di
import pytest
from modern_di_pytest import expose, modern_di_fixture

from app import ioc
from app.ioc import Dependencies
from app.services import EmailClient


@pytest.fixture
def di_container() -> typing.Iterator[modern_di.Container]:
    with modern_di.Container(groups=ioc.ALL_GROUPS) as container:
        container.validate()  # optional fail-fast; nothing validates the graph implicitly
        yield container


# Bulk: every Provider on each group becomes a pytest fixture
# named after the class attribute. Pass several groups in one call.
expose(Dependencies)

# Manual: turn a single type or Provider into a named fixture.
email_client = modern_di_fixture(EmailClient)

Tests then receive resolved dependencies by name:

from app.services import EmailClient, UserService


def test_listing(user_service: UserService) -> None:  # generated by expose(Dependencies)
    assert user_service.list_users() == []


def test_email(email_client: EmailClient) -> None:  # generated manually
    email_client.send("hi")

Pointing a fixture at a child container

import typing

import modern_di
import pytest
from modern_di_pytest import modern_di_fixture

from app.services import UserService


@pytest.fixture
def request_container(
    di_container: modern_di.Container,
) -> typing.Iterator[modern_di.Container]:
    with di_container.build_child_container(scope=modern_di.Scope.REQUEST) as container:
        yield container


request_user_service = modern_di_fixture(UserService, container_fixture="request_container")

Overrides

Use Container.override(); overrides are shared across the container tree. Generated fixtures resolve during test setup, so apply the override in a fixture they depend on. Overriding di_container in the test module does that:

import typing

import modern_di
import pytest

from app.ioc import Dependencies
from app.services import UserService
from tests.fakes import FakeRepo


@pytest.fixture
def di_container(di_container: modern_di.Container) -> typing.Iterator[modern_di.Container]:
    with di_container.override(Dependencies.user_repo, FakeRepo()):
        yield di_container


def test_with_override(user_service: UserService) -> None:
    assert user_service.list_users() == []

API

modern_di_fixture(dependency, *, container_fixture="di_container", name=None, pytest_scope="function")

Turn a single dependency into a pytest fixture. dependency is either a type or a Provider; the generated fixture resolves it through container.resolve_dependency. The returned object is a real pytest fixture; assign it to a module-level name and pytest will collect it.

expose(*groups, container_fixture="di_container", pytest_scope="function", module=None)

Walk each Group subclass in groups and install one pytest fixture per Provider class attribute onto the caller's module. Fixture names equal the class-attribute names. Non-Provider class attributes are skipped. A duplicate attribute name across groups raises ValueError, and calling it with no groups raises TypeError. Pass module= explicitly when stack introspection cannot identify the caller.

πŸ“¦ PyPI

πŸ“ License

Part of modern-python

Built on modern-di, a dependency-injection framework with an IoC container and scopes.

Browse the full list of templates and libraries in modern-python; the org profile has the categorized index.

About

Pytest integration for modern-di that turns DI dependencies into fixtures

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Contributors

Languages