Skip to content

Testing Dependencies with Overrides

Overriding dependencies during testing

There are some scenarios where you might want to override a dependency during testing.

You don't want the original dependency to run (nor any of the sub-dependencies it might have).

Instead, you want to provide a different dependency that will be used only during tests (possibly only some specific tests), and will provide a value that can be used where the value of the original dependency was used.

Use cases: external service

An example could be that you have an external authentication provider that you need to call.

You send it a token and it returns an authenticated user.

This provider might be charging you per request, and calling it might take some extra time than if you had a fixed mock user for tests.

You probably want to test the external provider once, but not necessarily call it for every test that runs.

In this case, you can override the dependency that calls that provider, and use a custom dependency that returns a mock user, only for your tests.

Use the fast_depends.dependency_provider object

For these cases, your FastDepends library has an object dependency_provider with dependency_overrides attribute, it is a simple dict.

To override a dependency for testing, you put as a key the original dependency (a function), and as the value, your dependency override (another function).

And then FastDepends will call that override instead of the original dependency.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
from fast_depends import Depends, inject, dependency_provider

def original_dependency():
    raise NotImplementedError()

def override_dependency():
    return 1

@inject
def func(d = Depends(original_dependency)):
    return d

dependency_provider.override(original_dependency, override_dependency)
# or
dependency_provider.dependency_overrides[original_dependency] = override_dependency

def test():
    assert func() == 1

Use pytest.fixture

Tip

dependency_provider is a library global object. Override dependency at one place, you override it everywhere.

So, if you don't wish to override dependency everywhere, I extremely recommend to use the following fixture for your tests

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import pytest
from fast_depends import dependency_provider, inject, Depends

# Base code

def base_dep():
    return 1

def override_dep():
    return 2

@inject
def func(d = Depends(base_dep)):
    return d

# Tests

@pytest.fixture
def provider():
    yield dependency_provider
    dependency_provider.clear() # (1)!

def test_sync_overide(provider):
    provider.override(base_dep, override_dep)
    assert func() == 2
  1. Drop all overridings