【问题标题】:py.test patch on fixture夹具上的 py.test 补丁
【发布时间】:2018-10-07 10:53:36
【问题描述】:

我使用以下内容来模拟 py.test 测试的常量值:

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

这模拟了测试和 Thing 中使用的 DELAY_TIME,这是我所期望的。

我想对这个文件中的所有测试都这样做,所以我尝试了

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

但这似乎没有相同的效果。

这里有一个类似的问题:pytest-mock mocker in pytest fixture,但那里的模拟似乎是以非装饰方式完成的。

【问题讨论】:

    标签: python mocking pytest


    【解决方案1】:

    我想说通过装饰器进行修补并不是这里的最佳方法。我会使用上下文管理器:

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

    这样,补丁在测试拆解时完全恢复。

    【讨论】:

    【解决方案2】:

    pytest 通过monkeypatch fixture 提供内置补丁支持。因此,要为文件中的所有测试修补常量,您可以创建以下 autouse 夹具:

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

    如果您不想在测试中导入ConstantsModule,可以使用字符串,请参阅full API reference

    【讨论】:

    • 注意monkeypatch 是一个函数范围的fixture,所以你的测试会引发ScopeMismatch
    • 哎呀,这会教我不要测试我发布的代码。感谢您的提醒,我已经更正了。
    猜你喜欢
    • 2020-10-29
    • 2013-12-28
    • 2019-02-02
    • 2022-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-30
    相关资源
    最近更新 更多