正如doc"Where to patch"所说,我们需要修补查找对象的位置(而不是定义对象的位置);所以我明白,不可能——比方说——为特定路径创建可重用补丁
假设有几个模块导入一个要模拟的对象
# file_a.py
from foo.goo.hoo import settings
# file_b.py
from foo.goo.hoo import settings
# file_c.py
from foo.goo.hoo import settings
我想知道是否有一种方法可以创建一个装饰器,例如:
@mock_settings
def test_whatever(self, settings_mock):
...
而不是此解决方案:
@patch("some_module.file_a.settings")
def test_whatever(self, settings_mock):
...
@patch("some_module.file_b.settings")
def test_whatever(self, settings_mock):
...
@patch("some_module.file_c.settings")
def test_whatever(self, settings_mock):
...
如问题中所述,要修补对象,必须修补其在待测试模块中的引用(如果使用
from ...import
导入对象)。要在多个模块中对其进行修补,可以使用相同的模拟对所有这些模块进行修补,并使用该模拟。如果您事先知道要修补哪些模块,您可以这样做。如果您事先不知道它们,您必须尝试在所有加载的模块中修补对象,这可能会变得更加复杂
我将展示一个使用pytest和pytest夹具的示例,因为这更紧凑;您可以将其包装在装饰器中,以便在
unittest
中使用,但这不会改变基本情况。考虑到我们有一个需要在几个模块中嘲笑的类:class\u to\u mock.py
module1.py
module2.py
现在,您可以编写一个fixture,一次模拟所有这些模块中的类(为了简单起见,这里使用
pytest-mock
):这可用于测试两个模块:
如果您想要在所有加载的模块中模拟类的通用版本,您可以使用以下内容替换该夹具:
这将适用于这个特定的例子-为了概括这一点,它必须考虑更多的对象类型,类应该是可配置的,并且可能会有更多的问题-与更简单的版本相反,在这里你只需要枚举要修补的模块,这将一直有效。p>
在
unittest.setUp
中,您可以通过将mock放在实例变量中来执行类似的操作,尽管这样做不太优雅,因为您还负责停止mock:您也可以将其包装在装饰器中,以至少部分地回答您最初的问题:
当然,如果需要,您也可以对更通用的版本执行相同的操作
还请注意,我跳过了使用
import ...
导入对象的简单情况。在这种情况下,您必须修补原始模块。在通用夹具中,您可能希望始终添加这种情况相关问题 更多 >
编程相关推荐