python-dependency-injector icon indicating copy to clipboard operation
python-dependency-injector copied to clipboard

Can't mix @pytest.fixture with @inject together

Open Sukonnik-Illia opened this issue 2 years ago • 1 comments
trafficstars

If we have pytest.fixture based on generator (yield statement and some cleanup after it), we can't get our objects through dependency injection.

import pytest

from dependency_injector import containers, providers
from dependency_injector.wiring import inject, Provide


class Container(containers.DeclarativeContainer):
    my_database = providers.Singleton(list)


def setup_module():
    c = Container()
    c.wire(modules=[__name__])


@pytest.fixture
@inject
def clean_db(db: list = Provide[Container.my_database]):
    yield db
    # Here would be good to clean database after test
    while db:
        db.pop()


def test_second(clean_db):
    clean_db.append('world')
    assert clean_db == ['world']

Raising an error:

$ pytest test_containers.py
==================================================================================== test session starts =====================================================================================
platform linux -- Python 3.9.9, pytest-7.2.0, pluggy-1.0.0
collected 1 item                                                                                                                                                                             

test_containers.py F                                                                                                                                                                   [100%]

========================================================================================== FAILURES ==========================================================================================
________________________________________________________________________________________ test_second _________________________________________________________________________________________

clean_db = <generator object clean_db at 0x7fdda1b800b0>

    def test_second(clean_db):
>       clean_db.append('world')
E       AttributeError: 'generator' object has no attribute 'append'

test_containers.py:26: AttributeError
================================================================================== short test summary info ===================================================================================
FAILED test_containers.py::test_second - AttributeError: 'generator' object has no attribute 'append'
===================================================================================== 1 failed in 0.07s ======================================================================================

For now, I'm bypassing this error by having functions like:

@inject
def _get_db(db: list = Provide[Container.my_database]):
    return db

And use such functions in my generator fixtures, but that's like doing dependency injection manually.

Sukonnik-Illia avatar Dec 13 '22 11:12 Sukonnik-Illia