如何使用assertRaises()对python类的_init___;()方法进行单元测试?

如何使用assertRaises()对python类的_init___;()方法进行单元测试?,python,unit-testing,exception,Python,Unit Testing,Exception,我有一门课: class MyClass: def __init__(self, foo): if foo != 1: raise Error("foo is not equal to 1!") 如果单元测试旨在确保传递给构造函数的错误参数正确,则会引发错误: def testInsufficientArgs(self): foo = 0 self.assertRaises((Error), myClass = MyClass(Error, foo))

我有一门课:

class MyClass:
def __init__(self, foo):
    if foo != 1:
        raise Error("foo is not equal to 1!")
如果单元测试旨在确保传递给构造函数的错误参数正确,则会引发错误:

def testInsufficientArgs(self):
    foo = 0
    self.assertRaises((Error), myClass = MyClass(Error, foo))
但是我得到

NameError: global name 'Error' is not defined

为什么??我应该在哪里定义这个错误对象?我认为它是作为默认异常类型内置的,不?

本例中的“错误”可以是任何异常对象。我想您可能已经阅读了一个代码示例,该示例将其用作元语法占位符,意思是“适当的异常类”

所有异常的基类都称为“Exception”,其大多数子类都是所涉及错误类型的描述性名称,例如“OSError”、“ValueError”、“NameError”、“TypeError”

在这种情况下,适当的错误是“ValueError”(foo的值是错误的,因此是ValueError)。我建议将脚本中的“Error”替换为“ValueError”

这是您试图编写的代码的完整版本,我复制了所有内容,因为您的原始示例中有一个奇怪的关键字参数,似乎与赋值混淆,我使用“Fail除非”函数名,因为这是函数的非别名名称:

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”中存在其他单元测试框架修复的缺陷。您将注意到,不可能从调用上下文访问exception对象。如果要解决此问题,必须在UnitTest的子类中重新定义该方法:

这是一个正在使用的it示例:

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函数,并对其进行了轻微的修改。

我认为您考虑的是s。将描述中的“错误”一词替换为“异常”,您应该可以继续:-)

这个怎么样:

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()

您可以在顶部将“class Error”定义为Exception的子类,并在本例中使用它来代替Exception(如果愿意的话)。下面是您出错的地方,下面是您想要的,下面是您打算编写的代码。这可能是我见过的最好的答案。self.failUnlessRaises现在不推荐使用。改为使用self.assertRaises@LoveMeSomeCode
\uuuu init\uuuu
函数通常不返回任何值。典型的
unittests
对于函数,通过函数测试返回值。通常建议您也测试
\uuuuu init\uuuu
函数吗?如果是这样的话,您是否通过直接访问
\uuuuu init\uuuu
所属类的实例属性来检查
\uuuu init\uuuu
函数内部更改的值?@alpha_989我想说,一般来说,如果init函数有任何破坏性行为或与外部源的连接,我会测试它们,例如,连接到数据库、打开文件等。我的大多数类只会在那里初始化一些变量,所以我不必费心。不过我很懒,通常只是对过去坏掉的东西进行测试。