如何使用assertRaises()对python类的__init __()方法进行单元测试?
时间:2020-03-06 14:19:13 来源:igfitidea点击:
我有一堂课:
class MyClass: def __init__(self, foo): if foo != 1: raise Error("foo is not equal to 1!")
和应该确保正确传递给构造函数的不正确的arg的单元测试会引发错误:
def testInsufficientArgs(self): foo = 0 self.assertRaises((Error), myClass = MyClass(Error, foo))
但是我明白了
NameError: global name 'Error' is not defined
为什么?我应该在哪里定义此Error对象?我认为它是作为默认异常类型内置的,不是吗?
解决方案
在此示例中,"错误"可以是任何异常对象。我认为我们可能已经阅读了一个代码示例,该示例将其用作元语义的占位符,表示"适当的异常类"。
所有异常的基类都称为"异常",其大多数子类是所涉及错误类型的描述性名称,例如" OSError"," ValueError"," NameError"," TypeError"。
在这种情况下,适当的错误是" ValueError"(foo的值是错误的,因此是ValueError)。我建议我们在脚本中将"错误"替换为" ValueError"。
这是我们要编写的代码的完整版本,我正在复制所有内容,因为在原始示例中我们有一个奇怪的关键字参数,我们似乎正在与赋值进行合并,并且我使用的是'failUnless'函数名称,因为这是该函数的非别名:
class MyClass: def __init__(self, foo): if foo != 1: raise ValueError("foo is not equal to 1!") import unittest class TestFoo(unittest.TestCase): def testInsufficientArgs(self): foo = 0 self.failUnlessRaises(ValueError, MyClass, foo) if __name__ == '__main__': unittest.main()
输出为:
. ---------------------------------------------------------------------- Ran 1 test in 0.007s OK
单元测试库" unittest"中存在一个其他单元测试框架已修复的缺陷。我们会注意到,不可能从调用上下文中访问异常对象。如果要解决此问题,则必须在UnitTest的子类中重新定义该方法:
这是一个正在使用的示例:
class TestFoo(unittest.TestCase): def failUnlessRaises(self, excClass, callableObj, *args, **kwargs): try: callableObj(*args, **kwargs) except excClass, excObj: return excObj # Actually return the exception object else: if hasattr(excClass,'__name__'): excName = excClass.__name__ else: excName = str(excClass) raise self.failureException, "%s not raised" % excName def testInsufficientArgs(self): foo = 0 excObj = self.failUnlessRaises(ValueError, MyClass, foo) self.failUnlessEqual(excObj[0], 'foo is not equal to 1!')
我已经从python2.5的unittest.py复制了failUnlessRaises函数,并对其做了一些修改。
我认为我们正在考虑例外。用Exception替换描述中的Error一词,我们应该会很好:-)
这个怎么样:
class MyClass: def __init__(self, foo): if foo != 1: raise Exception("foo is not equal to 1!") import unittest class Tests(unittest.TestCase): def testSufficientArgs(self): foo = 1 MyClass(foo) def testInsufficientArgs(self): foo = 2 self.assertRaises(Exception, MyClass, foo) if __name__ == '__main__': unittest.main()