Provider overriding¶
You can override any provider with another provider.
When provider is overridden it calls to the overriding provider instead of providing the object by its own.
This helps in testing. This also helps in overriding API clients with stubs for the development or staging environment.
To override a provider you need to call the Provider.override() method. This method receives
a single argument called overriding. If the overriding value is a provider, this provider
is called instead of the original. If value is not a provider, this value is returned instead of
calling the original provider.
importdataclasses importunittest.mock fromdependency_injectorimport containers, providers classApiClient: ... classApiClientStub(ApiClient): ... @dataclasses.dataclass classService: api_client: ApiClient classContainer(containers.DeclarativeContainer): api_client_factory = providers.Factory(ApiClient) service_factory = providers.Factory( Service, api_client=api_client_factory, ) if __name__ == "__main__": container = Container() # 1. Use .override() to replace the API client with stub container.api_client_factory.override(providers.Factory(ApiClientStub)) service1 = container.service_factory() assert isinstance(service1.api_client, ApiClientStub) # 2. Use .override() as a context manager to mock the API client in testing with container.api_client_factory.override(unittest.mock.Mock(ApiClient)): service2 = container.service_factory() assert isinstance(service2.api_client, unittest.mock.Mock) # 3. Use .reset_override() to get back to normal container.api_client_factory.reset_override() service3 = container.service_factory() assert isinstance(service3.api_client, ApiClient)
You can override a provider multiple times. In that case the latest overriding value will be
used. The rest of the overriding values will form a stack.
To reset an overriding you can use the Provider.reset_override() or
Provider.reset_last_overriding() methods.
You can use a context manager for overriding a provider with Provider.override():. The
overriding will be reset when context closed.