0

I want to separate DB configuration before test and test itself.

Let's say I have fixture_1 (user object) with method get_friends.
get_friends making calls to DB, well I should mock some calls beforehead.
I did the decorator below for this purpose, but I can't pass required fixture parameters (*a, **kw) to this function.
Pytest just not triggering on it, how I can do it?

The second decoration is just to avoid typing and wrapping decorator for every test_db_func.

P.S. please tell me if it's a bad idea. I found this one question How do I make pytest fixtures work with decorated functions? but this will force me to wrap every test_db_func.

def decorator(test_db_func):
    @functools_wraps(test_db_func)
    def wrapper(unit_func, *a, **kw):
        @functools_wraps(unit_func)
        def unit_func_params(*unit_func_args, **unit_func_kwargs):
            # Prepare DB for test
            test_db_func(*a, **kw)  # Should pass fixtures to this func
            unit_func(*unit_func_args, **unit_func_kwargs)
            test_db_func(*a, **kw)  # Assertions after yield
        return unit_func_params

    return wrapper


@test_db_func
def test_x(fixture_1, fixture_2):
    assert fixture_1.get_friends(fixture_2)


@decorator
def test_db_func(db_fixture):
    db_fixture.return_value = 'foo'
    yield
    db_fixture.assert_called_once ...
salius
  • 918
  • 1
  • 14
  • 30

1 Answers1

1

It is difficult to understand what is going on with multiple layers of decorators on a good day. It's also difficult to predict what Pytest is going to do with a decorated generator fixture.

If fixture_1 and fixture_2 are defined in another module, then this is how Pytest goes about 'decorating' fixtures.

@pytest.fixture()
def fixture_1(fixture_1):
    fixture_1.return_value = 'foo'
    yield fixture_1


@pytest.fixture()
def fixture_2(fixture_2):
    fixture_2.return_value = 'foo'
    yield fixture_2


def test_x(fixture_1, fixture_2):
    assert fixture_1.get_friends(fixture_2)

If original fixtures are in the same module or multiple mockings are needed, place in a Test Class.

Guy Gangemi
  • 1,533
  • 1
  • 13
  • 25