如何为未捕获的异常处理程序编写单元测试



我有一个函数来捕获未捕获的异常,如下所示。有没有办法编写一个单元测试来执行uncaught_exception_handler()函数,但正常退出测试?

import logging
def config_logger():
# logger setup here
def init_uncaught_exception_logger(logger):
'''Setup an exception handler to log uncaught exceptions.
This is typically called once per main executable.
This function only exists to provide a logger context to the nested function.
Args:
logger (Logger): The logger object to log uncaught exceptions with.
'''
def uncaught_exception_handler(*exc_args):
'''Log uncaught exceptions with logger.
Args:
exc_args: exception type, value, and traceback
'''
print("Triggered uncaught_exception_handler")
logger.error("uncaught: {}: {}n{}".format(*exc_args))
sys.excepthook = uncaught_exception_handler
if __name__ == '__main__':
LOGGER = config_logger()
init_uncaught_exception_logger(LOGGER)
raise Exception("This is an intentional uncaught exception")

与其测试是否为未捕获的异常调用函数,不如测试是否安装了excepthook,以及手动调用函数时该函数是否做了正确的事情。这为excepthook在实际使用中的表现提供了很好的证据。您需要将uncaught_exception_handler移到init_uncaught_exception_logger之外,以便您的测试可以更轻松地访问它。

assert sys.excepthook is uncaught_exception_handler
with your_preferred_output_capture_mechanism:
try:
1/0
except ZeroDivisionError:
uncaught_exception_handler(*sys.exc_info())
assert_something_about_captured_output()

如果您想通过未捕获的异常实际调用excepthook,那么您需要启动一个子流程并检查其输出。subprocess模块就是实现这一目标的途径。

为了编写关于引发异常的断言,可以使用pytest.raises作为上下文管理器,如下所示:

带提升(expected_exception:exception[,match][,message](

import pytest
def test_which_will_raise_exception():
with pytest.raises(Exception):
# Your function to test.

现在,只有当pytest.raises上下文管理器下的任何代码将引发作为参数提供的异常时,此单元测试才会通过。在这种情况下,它是Exception

最新更新