lime_test_component_registrations¶
The lime_test_component_registrations naming convention is a mechanism for injecting custom component registrations into the service locator during tests. When a service locator is bootstrapped, it picks up every fixture available to the test whose name starts with lime_test_component_registrations.
Each such fixture must return a list[ComponentRegistration].
How it works¶
All service locator fixtures (service_locator, task_handler_service_locator, webserver_service_locator, etc.) collect component registrations from every fixture in the test's fixture closure whose name begins with lime_test_component_registrations. This happens before the container is bootstrapped, so your registrations can override production components.
Like any pytest fixture, a registrations fixture takes effect only when it is part of the test's fixture closure — activate it with @pytest.mark.usefixtures(...), declare it as a test parameter, or define it with autouse=True to apply it to every test in its scope.
Replacement vs. new registration
A registration with meta=ComponentRegistrationMeta(label="test") replaces the production registration for the same service — if the service is not registered by the bootstrapped service, the registration is silently dropped. To register a brand-new service that production does not know about, omit meta.
Naming variants¶
Base name¶
lime_test_component_registrations is the conventional name for a single set of registrations defined in a test module or conftest.py. Define it with autouse=True when the registrations should apply to every test in that scope:
import pytest
from lime_core.dependencies import (
ComponentRegistration,
ComponentRegistrationMeta,
)
@pytest.fixture(autouse=True)
def lime_test_component_registrations() -> list[ComponentRegistration]:
return [
ComponentRegistration(
service=MyService,
factory=FakeMyService,
lifestyle="scoped",
meta=ComponentRegistrationMeta(label="test"),
)
]
Suffixed name¶
Adding a suffix (by convention separated with a double underscore) creates a named variant. Several variants can coexist — every active one is collected — and each test opts in to the variants it needs:
@pytest.fixture
def lime_test_component_registrations__failing_repo() -> list[ComponentRegistration]:
return [
ComponentRegistration(
service=MyRepository,
factory=FailingMyRepository,
lifestyle="scoped",
meta=ComponentRegistrationMeta(label="test"),
)
]
Activate it on a per-test basis:
@pytest.mark.usefixtures("lime_test_component_registrations__failing_repo")
def test_error_is_handled_gracefully():
...
Common use case: replacing a service with a test double¶
The primary use case is swapping out a production component for a fake or stub that behaves in a controlled way during the test: