我如何修补/模拟logging.getlogger()

时间:2013-09-19 17:33:46

标签: python unit-testing python-3.x mocking

我有我要测试的代码:

log = logging.getLogger(__name__)


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

但我无法弄清楚如何断言使用'Init'调用log.debug

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

我确定它很简单,但我无法想象它!

提前感谢您提供的任何帮助!

5 个答案:

答案 0 :(得分:29)

替代解决方案,可让您验证您是否也使用了正确的记录器:

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')

答案 1 :(得分:25)

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

with mock.patch('mymod.log') as log_mock:
    # test code
    log_mock.debug.assert_called_with('Init')

答案 2 :(得分: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()

答案 3 :(得分:0)

这个问题我来晚了,但是解决这个问题的另一种方法是:

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

    a = A()
    mocked_log.debug.assert_called_once_with('Init')

答案 4 :(得分: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')