【发布时间】:2020-08-04 15:40:09
【问题描述】:
我在 ClassA 的一个类上运行了一些单元测试。此类具有调用ClassB 的方法。 ClassA 和 ClassB 位于单独的模块中,class_A.py 和 class_B.py。这两个模块都有logger 函数,在该模块中全局可用。
在测试ClassA 的方法期间,我想禁止记录日志消息。使用mock.patch 可以直接为class_A.py 中的记录器执行此操作。但我还没有找到修补class_B.py 中的记录器的方法。
这里是一些示例代码:
unittest_file.py
import unittest
import class_A
class TestClassA(unittest.TestCase):
def setUp(self):
pass
def test_method(self):
my_class_A = class_A.ClassA()
my_class_A.run_method()
def tearDown(self):
pass
class_A.py
import logging
from class_B import ClassB
logger = logging.getLogger(__name__)
class ClassA:
run_method(self):
my_class_B = ClassB()
my_class_B.do_something()
logger.info("Running method on Class A")
class_B.py
import logging
logger = logging.getLogger(__name__)
class ClassB:
do_something(self):
logger.info("Doing something on Class B")
要修补class_A.py 中的记录器,我可以将@patch('__main__.unittest_file.ClassA.logger', autospec=True) 作为装饰器添加到test_method() 方法中。
但我也无法直接访问 class_B.py 中的记录器来修补它。
我最接近的解决方案是这样的:
@patch(eval('__main__.unittest_file.class_A.ClassB.__module__')['logger'])
但应用于模块名称的eval() 函数不会保留导入位置,因此它不会修补正确命名空间中的记录器。
我知道我可以通过将class_A.py 中的import 语句更改为import class_B 而不是from class_B import ClassB 来轻松解决这个问题,但我不想编辑class_A.py 或class_B.py 中的代码,所以这不是我要找的答案。
我也知道可以通过禁用日志记录来解决这个问题,如this question,但我更感兴趣的是能够微调我对要测试的代码的不同部分的控制,所以这不是答案我也在找。
我的问题是: 有没有一种方法可以让我从导入的对象导航到其父模块中的其他对象,同时保持在同一个命名空间中?
【问题讨论】:
-
所以您只想修补记录器,而保留其他所有内容?
-
现在,是的,我只是想控制日志输出。
标签: python unit-testing import monkeypatching