I have this code that I want to test:
log = logging.getLogger(__name__) class A(object): def __init__(self): log.debug('Init')
but I cannot figure out how to assert that log.debug was called with 'Init'
I tried patching logger but inspecting it I only found a getLogger mock.
I'm sure its simple, but I just cant figure it!
Thanks in advance for any and all help!
getLogger(name) is typically executed. The getLogger() function accepts a single argument - the logger's name. It returns a reference to a logger instance with the specified name if provided, or root if not. Multiple calls to getLogger() with the same name will return a reference to the same logger object.
Mock The logging Module Using the same example as before, the test would be: # test.py X from unittest import TestCase from unittest. mock import patch from example import method_with_logging class TestExample(TestCase): @patch("example.logging.info") def test_logging(self, info_mock): method_with_logging() info_mock.
The level set in the logger determines which severity of messages it will pass to its handlers. The level set in each handler determines which messages that handler will send on." Check under Handlers: http://docs.python.org/2.7/howto/logging.html#logging-advanced-tutorial.
The inbuilt logging module in python requires some handful of lines of code to configure log4j-like features viz - file appender, file rotation based on both time & size. For one-liner implementation of the features in your code, you can use the package autopylogger .
The getLogger () method of a Logger class used find or create a logger. If there is a logger exists with the passed name then the method will return that logger else method will create a new logger with that name and return it. There are two types of getLogger () method depending upon no of the parameter passed.
There are some alternatives as well, for example you can mock the logging module, use the LogCapture from the testfixtures package or register your own stream handler. 1. Use The AssertLogs Context Manager From unitest
You can use patch.object()on the actual logging object. that lets you verify that you're using the correct logger too: 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')
getLogger (String name, String resourceBundleName): This method is used to find or creates a logger with the passed name. If a logger has already been created with the given name it is returned.
You can use patch.object()
on the actual logging object. that lets you verify that you're using the correct logger too:
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')
Alternatively, if you're using Pytest, then it already has a fixture that captures logs for you:
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"
More info in the pytest docs on logging
Assuming log
is a global variable in a module mymod
, you want to mock the actual instance that getLogger
returned, which is what invokes debug
. Then, you can check if log.debug
was called with the correct argument.
with mock.patch('mymod.log') as log_mock: # test code log_mock.debug.assert_called_with('Init')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With