assertRaises失败,即使是callable引发了所需的异常(python,unitest)

Ale*_*lex 11 python unit-testing

我有以下测试代码检查函数中的异常引发.我希望测试通过,但是会指示失败.这是测试代码:

import unittest

# define a user-defined exception
class MyException(Exception):
    def __str__(self):
        return repr("ERROR: Just raised my exception!")

# this is my main class with a method raising this exception
class MyMainObject(object):

    def func(self):
        raise MyException()

# the test class
class TestConfig(unittest.TestCase):

    def test_1(self):

        other = MyMainObject()
        self.assertRaises(MyException, other.func())

# calling the test
if __name__ == '__main__':    
    unittest.main()
Run Code Online (Sandbox Code Playgroud)

other.func()被调用的断言语句,MyException提高(可以容易地检查).因此,assertRaises测试应该通过测试,因为other.func()与...相关MyException,但是:

....
MyException: 'ERROR: Just raised my exception!'

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (errors=1)
Run Code Online (Sandbox Code Playgroud)

我没有看到什么问题,所以我会很感激这个问题的一些意见.

Mar*_*ers 22

assertRaises为你调用这个功能.通过自己调用它,可以在测试之前 引发异常assertRaises.

将您的代码更改为:

self.assertRaises(MyException, other.func)
Run Code Online (Sandbox Code Playgroud)

它会正常工作.或者,您可以使用assertRaises上下文管理器(python 2.7及更高版本):

with self.assertRaises(MyException):
    other.func()
Run Code Online (Sandbox Code Playgroud)

使用assertRaises上下文管理器的另一个好处是,您现在可以检索异常实例并对其执行进一步测试:

with self.assertRaises(MyException) as raises_cm:
    other.func()

exception = raises_cm.exception
self.assertEqual(exception.args, ('foo', 'bar'))
Run Code Online (Sandbox Code Playgroud)


小智 7

由于语言的规则,在输入被调用函数的代码之前评估参数(这通常是一件好事).因此,assertRaises无法捕获在评估参数期间发生的异常.解决方法(在多个API中)是将callable传递给类似的方法assertRaises,因此他们可以在可以控制的位置以及可以捕获异常的位置对其进行评估.如果整个参数是一个方法调用,那么绑定方法的魔力可以让你非常优雅地说明这一点,没有lambda或有这样的愚蠢:

self.assertRaises(MyException, other.func) # <- note, no parentheses after func
Run Code Online (Sandbox Code Playgroud)

  • @testerjoe2 函数后面的所有内容,包括像 `age=-10` 这样的关键字参数(这就是 `**kwds` 代表的意思),都会传递给可调用函数。你应该直接创建 `ValueError` 对象,因为它的构造不需要像函数调用一样被延迟(如果你不 `raise` 异常对象是无害的),所以你需要: `self.assertRaises(ValueError) (“错误:人的年龄不能为负数。”),person.set_age_ethod,-10)`。 (2认同)