47

我有要测试的代码:

log = logging.getLogger(__name__)


class A(object):
    def __init__(self):
        log.debug('Init')

但我不知道如何断言 log.debug 是用“Init”调用的

我尝试修补记录器,但检查它我只发现了一个 getLogger 模拟。

我敢肯定它很简单,但我就是想不通!

提前感谢您的任何帮助!

4

6 回答 6

67

您可以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 文档中有关日志记录的更多信息

于 2014-03-03T00:29:18.223 回答
36

假设log是一个模块中的全局变量mymod,您想模拟getLogger返回的实际实例,这就是调用debug. 然后,您可以检查是否log.debug使用正确的参数调用。

with mock.patch('mymod.log') as log_mock:
    # test code
    log_mock.debug.assert_called_with('Init')
于 2013-09-19T17:38:29.483 回答
2

我迟到了这个问题,但实现它的另一种方法是:

@patch('package_name.module_name.log')
def test_log_in_A(self, mocked_log):

    a = A()
    mocked_log.debug.assert_called_once_with('Init')
于 2019-08-31T17:36:45.327 回答
1

这是一个完整的例子

"""
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()

于 2020-05-29T10:28:59.370 回答
1

这也有效:

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')
于 2022-02-08T09:30:00.357 回答
0

更简单的...

只需修补日志记录模块本身。

# 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')
于 2021-04-01T21:33:55.950 回答