如何获得unittest中抛出的异常

时间:2014-01-17 07:47:24

标签: python django unit-testing

我有自己的例外,我想测试ex中的更远的字段然后消息。 读这个thread我尝试了使用上下文的想法。我写了这个通用函数

def test_runtime_error(test, exception_type, message, display_parameter, path, callable_obj, *args):
    pdb.set_trace()
    with test.assertRaises(exception_type) as cx:
        callable_obj(*args)
    ex = cx.exception

    test.assertEqual(ex.message,message)
    test.assertEqual(ex.display_parameter,display_parameter)
    test.assertEqual(ex.path,path)

pathdisplay_parameter是我自己的特定字段。我不是在这里发明轮子,我从source中拿走了大部分。

我正在使用它

class ExceptionsTest(unittest.TestCase):
    def test_something(self):
         data = {"name" : "A"}
         obj = MyModel.objects.get(pk=1)
         test_runtime_error(self,CustomException, 'message', 'A', [], obj.create, data)

参数正确传递给callable_obj。该函数引发了预期的异常。但是在执行callable_obj之后,函数就会中断并且不会获取异常。顺便说一句,当我在测试中运行相同的代码时,它自己工作正常。

这里有什么不对?

1 个答案:

答案 0 :(得分:0)

这里的问题似乎是这一行:

pdb.set_trace()

如果您将其保留,但没有import pdb,则以下代码将失败:

E
======================================================================
ERROR: testRaises (__main__.ExceptionTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "./except.py", line 22, in testRaises
    self.verifyComplexException(MyException, 'asdf', RaiseException, 'asdf')
  File "./except.py", line 14, in verifyComplexException
    pdb.set_trace()
NameError: global name 'pdb' is not defined

----------------------------------------------------------------------
Ran 1 test in 0.000s

FAILED (errors=1)

符合您的描述。如果你确实添加了import pdb行,它将进入调试器,这是一个完全不同的行为,不能与退出E或退出F状态混淆,所以它不可能。

以下是基于此想法的完整示例,其按预期工作(在Apache 2.0下获得许可;请参阅my repo):

import unittest

class MyException(Exception):
    def __init__(self, message):
        self.message = message

def RaiseException(message):
    raise MyException(message)

class ExceptionTest(unittest.TestCase):
    def verifyComplexException(self, exception_class, message, callable, *args):
        with self.assertRaises(exception_class) as cm:
            callable(*args)

        exception = cm.exception
        self.assertEqual(exception.message, message)

    def testRaises(self):
        self.verifyComplexException(MyException, 'asdf', RaiseException, 'asdf')


if __name__ == '__main__':
    unittest.main()