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

时间:2018-11-22 14:31:35

标签: python unit-testing exception

我在下面具有捕获未捕获异常的功能。有什么方法可以编写将执行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")

2 个答案:

答案 0 :(得分:1)

与其测试是否为未捕获的异常调用了函数,不如测试已安装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 module是实现这一目标的方法。

答案 1 :(得分:0)

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

  

加薪(expected_exception:异常[,匹配] [,消息])

import pytest

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

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