简体   繁体   中英

py.test patch on fixture

I use the following to mock constant values for a test with py.test:

@patch('ConstantsModule.ConstantsClass.DELAY_TIME', 10)
def test_PowerUp():
    ...
    thing = Thing.Thing()
    assert thing.a == 1

This mocks DELAY_TIME as used in both the test, and in Thing, which is what I expected.

I wanted to do this for all the tests in this file, so I tried

@patch('ConstantsModule.ConstantsClass.DELAY_TIME', 10)
@pytest.fixture(autouse=True)
def NoDelay():
    pass

But that doesn't seem to have the same effect.

Here is a similar question: pytest-mock mocker in pytest fixture , but the mock seems done in a non-decorator way there.

I'd say patching via decorator is not the optimal approach here. I'd use the context manager:

import pytest
from unittest.mock import patch


@pytest.fixture(autouse=True)
def no_delay():
    with patch('ConstantsModule.ConstantsClass.DELAY_TIME', 10):
        yield

This way, patching is cleanly reverted on test teardown.

pytest provides builtin patching support via the monkeypatch fixture . So to patch the constant for all tests in the file you can create the following autouse fixture:

@pytest.fixture(autouse=True)
def no_delay(monkeypatch):
    monkeypatch.setattr(ConstantsModule.ConstantsClass, 'DELAY_TIME', 10)

If you don't want to have the ConstantsModule imported in your tests you can use a string, see the full API reference .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM