夹具上的py.test补丁

sg_*_*man 6 python mocking pytest

我使用以下方法通过py.test模拟常量值以进行测试:

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

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

我想对这个文件中的所有测试执行此操作,所以我尝试了

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

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

这是一个类似的问题:pytest夹具中的pytest-mock模拟程序,但该模拟似乎是通过非装饰器方式完成的。

hoe*_*ing 11

我会说通过装饰器打补丁不是这里的最佳方法。我会使用上下文管理器:

import pytest
from unittest.mock import patch


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

这样,修补在测试拆卸时可以完全恢复。


flu*_*lub 7

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

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

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

  • 请注意`monkeypatch` 是一个函数范围的fixture,因此您的测试将引发`ScopeMismatch`。 (2认同)
  • 哎呀,这会教我不要测试我发布的代码。谢谢你的提醒,我已经更正了。 (2认同)