I have a function that that involves setting up a logger:
app/src/app/pipelines.py
:
import logging
def get_log_handlers(filepath):
return [logging.FileHandler(filepath,
'w'),
logging.StreamHandler()
]
def function(results_dir):
log_handlers= get_log_handlers(f'{results_dir}\\log.txt')
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s %(levelname)s: %(message)s',
handlers=log_handlers
)
logger = logging.getLogger()
logger.info('---PARAMETERS---')
I would like to test that the logging is going as expected using pytest, but don't want to write to a file, so in my test file I call function
and monkeypatch a handler generation function so that a FileHandler
is omitted for the test:
app/tests/test_pipelines.py
:
from io import StringIO
import logging
def test_function(monkeypatch):
def mock_get_log_handlers(path):
nonlocal test_stream
return [logging.StreamHandler(test_stream)]
test_stream = StringIO()
monkeypatch.setattr('app.pipelines.get_log_handlers', mock_get_log_handlers)
function1('result_dir')
test_stream.seek(0)
content = test_stream.readlines()
assert content[0] == '---PARAMETERS---'
My mock is getting called, but nothing is getting written to the test_stream (AssertionError: assert [] == ['---PARAMETERS---']
).
What am I doing wrong?
I wasn't able to get my original solution working, but for anyone else with this issue, it seems like you should use the pytest caplog fixture. My working code looked like:
def test_function(monkeypatch, caplog):
#remove the FileHandler that is returned by get_log_handlers()
def mock_get_log_handlers(path):
return [logging.StreamHandler()]
monkeypatch.setattr('app.pipelines.get_log_handlers', mock_get_log_handlers)
#note logging level is specific to my basicConfig
with caplog.at_level(logging.INFO):
function1('result_dir')
assert caplog.messages == ['---PARAMETERS---']