py.test patch on fixture

馋奶兔 提交于 2019-12-22 05:07:30

问题


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.


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/50048080/py-test-patch-on-fixture

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!