如何用多个补丁动态装饰python unittest类
Posted
技术标签:
【中文标题】如何用多个补丁动态装饰python unittest类【英文标题】:How to dynamically decorate python unittest class with multiple patches 【发布时间】:2022-01-09 23:24:50 【问题描述】:一个函数在 source.py 中定义并在 use_source.py 中调用。我像这样从 test.py 修补它
source.py
def example_function():
print("I don't want this to run")
use_source.py
from source import example_function
def call_example_function():
example_function()
test.py
import unittest
from unittest.mock import patch
import use_source
file_names = ["use_source.example_function"]
def fake_function():
print("I want this to run instead")
@patch(file_names[0], new=fake_function)
class ExampleTest(unittest.TestCase):
def test_example(self):
use_source.call_example_function()
if __name__ == '__main__':
unittest.main()
但是,我有多个像 use_source.py 这样的文件要修补,所以这是我的问题
如何在给定目标列表的情况下动态调用补丁装饰器?
我正在寻找类似的东西
@patch_list(file_names, new=fake_function)
class ExampleTest(unittest.TestCase):
我可以这样做,但我要修补的文件数量很多且数量不定
@patch(file_names[0], new=fake_function)
@patch(file_names[1], new=fake_function)
class ExampleTest(unittest.TestCase):
最后,我正在寻找一个只修改test.py的解决方案
【问题讨论】:
【参考方案1】:我可以使用装饰器,但在测试的 SetupClass 方法中使用 patch.start()
import unittest
from unittest.mock import patch
import use_source
file_names = ["use_source.example_function"]
def fake_function():
print("I want this to run instead")
class ExampleTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
for file_name in file_names():
patch(file_name, new=fake_function).start()
def test_example(self):
use_source.call_example_function()
if __name__ == '__main__':
unittest.main()
运行 python test.py 产生与上面相同的输出,并允许我修补大量不同的方法!
【讨论】:
【参考方案2】:装饰器语法只是函数应用程序的语法糖。你可以写
class ExampleTest(unittest.TestCase):
...
for f in file_names:
ExampleTest = patch(f, new=fake_function)(ExampleTest)
我不确定这种方法与您找到的解决方案之间是否有任何显着差异。
【讨论】:
谢谢,但是使用上面的代码,我要么得到一个“分配前引用的局部变量'ExampleTest'”,要么不应用补丁,即打印“我不希望它运行” 我看不出局部变量错误的任何原因。你是把循环放在类语句中,还是放在之后? (应该在之后,如图所示。) 是的,局部变量错误出现在类语句中,但是如果我将循环放在类语句之后,则不会应用补丁以上是关于如何用多个补丁动态装饰python unittest类的主要内容,如果未能解决你的问题,请参考以下文章
为什么 Python 没有函数重载?如何用装饰器实现函数重载?
如何用 Decorator 装饰你的 Typescript?