ca9163d9
ca9163d9

Reputation: 29159

pytest fixture for mocked object setup?

I'm using pytest and I have 5+ tests that have the exactly same first five lines. Is it possible to create a setup function for the repeated code?

@mock.patch('abcde.xyz')
def test_1(mocked_function):
    x_mock = mock.Mock(X)
    x_mock.producer = mock.Mock()
    x_mock.producer.func2 = lambda : None
    mocked_function.return_value = x_mock # xyz() returns x_mock
    ......

@mock.patch('abcde.xyz')
def test_2(mocked_function):
    x_mock = mock.Mock(X)
    x_mock.producer = mock.Mock()
    x_mock.producer.func2 = lambda : None
    mocked_function.return_value = x_mock
    ......

@mock..... # more

Upvotes: 2

Views: 4844

Answers (2)

jeremyr
jeremyr

Reputation: 530

You should consider using a fixture as it recommended over classic setup/teardown methods.

From pytest documentation:

While these setup/teardown methods are simple and familiar to those coming from a unittest or nose background, you may also consider using pytest’s more powerful fixture mechanism which leverages the concept of dependency injection, allowing for a more modular and more scalable approach for managing test state, especially for larger projects and for functional testing.

For your example - considering that mocked_function is itself a fixture - it would be:

@pytest.fixture()
def mock_abcde_xyz(mocker):
    mocker.patch("abcde.xyz")

@pytest.fixture()
@pytest.mark.usefixtures("mock_abcde_xyz")
def patched_mocked_function(mocker, mocked_function):
    x_mock = mocker.Mock(X)
    x_mock.producer = mocker.Mock()
    x_mock.producer.func2 = lambda : None
    mocked_function.return_value = x_mock
    return mocked_function   


def test_1(patched_mocked_function):
    ......

def test_2(patched_mocked_function):
    ......

Note that I used pytest-mock instead of mock so that you can use 'mocker' fixture.

If you don't want pytest-mock, just do:

@pytest.fixture()
@mock.patch('abcde.xyz')
def patched_mocked_function(mocked_function):
    x_mock = mock.Mock(X)
    x_mock.producer = mock.Mock()
    x_mock.producer.func2 = lambda : None
    mocked_function.return_value = x_mock
    return mocked_function   


def test_1(patched_mocked_function):
    ......

def test_2(patched_mocked_function):
    ......

Upvotes: 2

Jiří Baum
Jiří Baum

Reputation: 6930

Yes, you can implement a setUp() (or setUpClass()) method.

Another way would be to implement a helper function, as you would in any other Python code.

Upvotes: 0

Related Questions