我有要测试的代码:
log = logging.getLogger(__name__)
class A(object):
def __init__(self):
log.debug('Init')
但我不知道如何断言 log.debug 是用“Init”调用的
我尝试修补记录器,但检查它我只发现了一个 getLogger 模拟。
我敢肯定它很简单,但我就是想不通!
提前感谢您的任何帮助!
我有要测试的代码:
log = logging.getLogger(__name__)
class A(object):
def __init__(self):
log.debug('Init')
但我不知道如何断言 log.debug 是用“Init”调用的
我尝试修补记录器,但检查它我只发现了一个 getLogger 模拟。
我敢肯定它很简单,但我就是想不通!
提前感谢您的任何帮助!
您可以patch.object()
在实际的日志记录对象上使用。这使您可以验证您是否也在使用正确的记录器:
logger = logging.getLogger('path.to.module.under.test')
with mock.patch.object(logger, 'debug') as mock_debug:
run_code_under_test()
mock_debug.assert_called_once_with('Init')
或者,如果您使用的是 Pytest,那么它已经有一个为您捕获日志的夹具:
def test_bar(caplog):
with caplog.at_level(logging.DEBUG):
run_code_under_test()
assert "Init" in caplog.text
# or, if you really need to check the log-level
assert caplog.records[-1].message == "Init"
assert caplog.records[-1].levelname == "DEBUG"
pytest 文档中有关日志记录的更多信息
假设log
是一个模块中的全局变量mymod
,您想模拟getLogger
返回的实际实例,这就是调用debug
. 然后,您可以检查是否log.debug
使用正确的参数调用。
with mock.patch('mymod.log') as log_mock:
# test code
log_mock.debug.assert_called_with('Init')
我迟到了这个问题,但实现它的另一种方法是:
@patch('package_name.module_name.log')
def test_log_in_A(self, mocked_log):
a = A()
mocked_log.debug.assert_called_once_with('Init')
这是一个完整的例子
"""
Source to test
"""
import logging
logger = logging.getLogger("abc")
def my_fonction():
logger.warning("Oops")
"""
Testing part
"""
import unittest
from unittest.mock import patch, MagicMock
abc_logger = logging.getLogger("abc")
class TestApp(unittest.TestCase):
@patch.object(abc_logger, "warning", MagicMock())
def test_my_fonction(self):
# When
my_fonction()
# Then
abc_logger.warning.assert_called_once()
这也有效:
from unittest.mock import patch
class Test(TestCase):
def test_logger(self):
with patch('logging.Logger.warning') as mocked_logger:
call_func()
mocked_logger.assert_called_once_with('log')
更简单的...
只需修补日志记录模块本身。
# File foo.py
import logging
log = logging.getLogger(__name__)
def main():
log.debug('Init')
# File foo_test.py
from unittest.mock import patch
import foo
@patch.object(foo, 'logging')
def test_log_debug_called(logging):
foo.main()
logging.debug.assert_called_with('Init')