I use the decorator to handle the exception in Python. Here is the decorator function:
def docker_exception_handler(func):
def wrapper(*args, **kwargs):
logger = logging.getLogger('docker_exception')
try:
func(*args, **kwargs)
except SubProcessException:
logger.critical(
f'Failed to pull {args[1]} in function {func.__name__}\n')
return wrapper
Now I would like to use Pytest when the SubProcessException raised this function is called. Something like:
@docker_exception_handler
def trigger_docker_error(class_name, docker_image):
raise PullDockerImageError
def test_docker_error():
with patch.object(customized_exceptions,
'docker_exception_handler') as mock:
trigger_docker_error("test", "test_docker_image")
mock.assert_called_once()
But the mock did not get the call, failed with message
AssertionError: Expected 'docker_exception_handler' to have been called once. Called 0 times
I do not know why.
Decorators applied in import time, so there is not much sense to mock them and asserting something in runtime.
In your case you could mock the logger and check if it was called with right arguments. Here I'm using mocker
fixture from pytest-mock
import functools
import logging
def exception_handler(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
logger = logging.getLogger('docker_exception')
try:
func(*args, **kwargs)
except Exception:
logger.critical(
f'Failed to pull {args[1]} in function {func.__name__}\n')
return wrapper
@exception_handler
def trigger_error(class_name, docker_image):
raise TypeError()
def test_error(mocker):
logger = logging.getLogger('docker_exception')
mock = mocker.patch.object(logger, 'critical')
trigger_error("test", "test_docker_image")
mock.assert_called_once()
mock.assert_called_with(f'Failed to pull test_docker_image in function trigger_error\n')
if __name__ == "__main__":
import pytest
pytest.main([__file__])