开发者

Mocking before importing a module

How can I patch and mock getLogger in this module under test (MUT):

# Start of the module under test
import logging
log = logging.getLogger('some_logger')
# ...

I would like to do:

mock_logging.getLogger.return_value = Mock()

However I can't create mock_logging before importing the MUT, but importing the MUT already calls get开发者_JS百科Logger...


This can be done by first importing and patching logging.getLogger and only then import your mut

import unittest
from unittest import mock

import logging
with mock.patch('logging.getLogger') as mock_method:
    import mut
mock_method.assert_called_once_with('some_logger')

Alternatively, useful when patching more than one method:

import unittest
from unittest import mock

import logging
mock_method = mock.patch('logging.getLogger').start()
import mut
mock_method.stop()
mock_method.assert_called_once_with('some_logger')


This would require importing the module without executing it first, which unfortunately for you won't work unless you do some fancy hacks like modifying the parse tree for the module, but you probably don't want to do that either.

What you could do is to modify these import-time reference after the import and replace them manually by mock-objects or reexecute the statements after your mock-object is install, though I know, that this is of limited use.


You need to import the module inside a mocked context and remove the module from sys.modules after importing so the mock doesn't persist in other tests that import mut:

import sys
from unittest import mock

with mock.patch("logging.getLogger") as mock_logging:
    import mut
    del sys.modules["mut"]
...

Alternatively with pytest:

import sys
import pytest

def mock_get_logger(name):
    print("mock logger name", name)

with pytest.MonkeyPatch().context() as ctx:
    ctx.setattr("", mock_get_logger)
    from main import app
    del sys.modules["main"]
...
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜