我正在对文件进行单元测试,而且我在类B中模拟属性或函数调用(self.logger.info
)时遇到问题。我有两个类A和B,B继承自A
import logging
class A(object):
def __init__(self):
self.logger = logging.getLogger()
在另一个模块中:
from A import A
class B(A):
def function(self):
self.logger.info("Hello")
我想模仿self.logger.info
不被调用。我试图使用patch('A.logging.info')
,但它没有用。我也试过了patch('A.logging.getLogger')
,但如果我在print type(self.logger)
测试时我function()
,我会得到一个记录对象而不是模拟对象。
答案 0 :(得分:0)
创建实例时,您的属性设置为。只需修补logging.getLogger
甚至logging.Logger.info
。
如果您修补logging.getLogger()
来电,则不必修补任何其他self.logger
来电,因为生成的模拟会处理其中的任何属性:
with mock.patch('logging.getLogger') as mock_log:
mock_logger = mock_log.return_value
b = B()
b.function()
mock_logger.info.assert_called_with('Hello')
使用模拟,使用logging.getLogger()
返回一个新的模拟对象(mock_log.return_value
object),然后任何访问self.logger.info
的尝试都返回mock_log.return_value.info
对象,使用Mock.assert_called_with()
method记录可测试的测试。
演示:
>>> import mock
>>> import logging
>>> class A(object):
... def __init__(self):
... self.logger = logging.getLogger()
...
>>> class B(A):
... def function(self):
... self.logger.info("Hello")
...
>>> with mock.patch('logging.getLogger') as mock_log:
... mock_logger = mock_log.return_value
... b = B()
... b.function()
... mock_logger.info.assert_called_with('Hello')
...
>>> mock_logger
<MagicMock name='getLogger()' id='4375059984'>
>>> mock_logger.info
<MagicMock name='getLogger().info' id='4374917008'>
>>> mock_logger.info.call_args
call('Hello')
答案 1 :(得分:0)
真正的问题是您要修补仅 info
记录器而非记录器。要做到这一点,你应该使用
patch.object(logging.getlogger(), 'info')
>>> from mock import patch
>>> with patch.object(logging.getLogger(), "info") as mock_info:
... B().function()
... print(mock_info.mock_calls)
... mock_info.assert_called_with("Hello")
[call('Hello')]
有趣的是logging.getLogger()
返回一个全局对象,所以即使在补丁上下文之前创建了B
对象,这个方法也能正常工作:
>>> b = B()
>>> with patch.object(logging.getLogger(), "info") as mock_info:
... b.function()
... print(mock_info.mock_calls)
... mock_info.assert_called_with("Hello")
...
[call('Hello')]