Python testcase模拟断言尝试除外

时间:2017-12-11 17:05:54

标签: python mocking

在我的代码中,我有:

def testcode(args):
    try:
        function()
    except Exception as e:
        print(e)

在我的测试用例中它包含:

with patch('module.function') as mock_func:
    mock_func.side_effect = _exception()
self.assertRaises(_exception(), testcode, args)

当我运行self.assertRaises时,它会到达except块并执行print(e)但不会引发异常。我无法在print语句后添加加注,因为我不想结束脚本。我怎样才能提出例外?

1 个答案:

答案 0 :(得分:0)

您需要重新raise例外,或者接受您的方法的调用者(包括您的测试)不会看到异常因为您在方法中处理该异常< / em>的

例外的一点是,您可以将堆栈向上移动到最近的except块,允许任何给定的调用者将其自己的调用者与其不应该知道的异常隔离开来。这意味着,当您的函数被编写时,它可能正在按预期工作:您已经创建它以便即使它抛出异常也可以完成对function()的调用,并且您通过打印恢复例外并继续前进。这意味着您的测试和规格需要更改,而不是您的生产代码。

def try_something_dangerous():
    try:
        do_dangerous_thing()
        return True   # The thing succeeded.
    except SomeImplementationDetailException:
        return False  # The thing failed in a way we were prepared for.
                      # Hide the failure from the outside world.

但是,有时您需要进行干预并仍然抛出异常:您可能希望记录异常(正如您通过print所做的那样),检查异常以查看是否重新抛出异常,或将异常包装在另一个包含其他有用信息(您正在处理哪些数据?)或抽象(由于LowLevelException而发生HighLevelException)的异常中。

Python有一个简单的语法,用于从except块中重新引发异常:Just call raise without an instance.

  

如果您需要确定是否引发了异常但不打算处理异常,则可以使用更简单的raise语句形式重新引发异常:

>>> try:
...     raise NameError('HiThere')
... except NameError:
...     print 'An exception flew by!'
...     raise
...
An exception flew by!
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
NameError: HiThere

因此,如果您想重新引发异常,请在此处执行此操作:

def testcode(args):
    try:
        function()
    except Exception as e:
        print(e)
        raise

...但要小心:这可能会使您的代码混乱或令人沮丧,因为您无条件地记录了异常,而没有处理它。如果调用者处理异常,他们可能不希望您进行额外的日志记录,如果他们不这样做,程序会以任何方式结束,您的日志可能也无济于事。调用者无法禁用您的print语句。相反,考虑在重新抛出之前包装异常,或者根本不处理异常并让调用代码负责处理它。