Python构造函数中的异常单元测试

13 投票
7 回答
12202 浏览
提问于 2025-04-15 12:15

我刚开始学习Python和编程,有一些关于unittest模块的问题。

我有一个类,在这个类的__init__方法里,我会做一些检查,看看传入的参数是否有问题。我想写一个unittest来检查在创建新实例时是否会出现这样的AssertionError。

在unittest模块中,可以使用assertRaises来测试调用某个函数时是否会抛出特定的异常,但这显然是针对类的方法的。那么,怎么才能正确地测试构造函数呢?

我知道我可以尝试用错误的参数创建类的实例,这样unittest会报告测试失败,但这样一来,测试在遇到第一个异常后就会停止。即使我把多个测试放在多个测试函数里,这样的做法看起来也不太优雅。

7 个回答

2

不知道这是否有帮助,但我遇到的问题是这样的:

self.assertRaises(Exception, MyFunction())

问题在于我不仅仅是传递了 MyFunction,而是直接调用了它,这导致了失败并抛出了异常。MyFunction 需要一个参数,如果没有传入参数,我希望它能失败。这个问题让我困扰了一段时间,直到我搞明白了:

self.assertRaises(Exception, MyFunction)

现在一切都正常了。

7

别去碰 assertRaises。它太复杂了。

这样做就行了:

class Test_Init( unittest.TestCase ):
    def test_something( self ):
        try:
            x= Something( "This Should Fail" )
            self.fail( "Didn't raise AssertionError" )
        except AssertionError, e:
            self.assertEquals( "Expected Message", e.message )
            self.assertEquals( args, e.args )

其他任何异常都会被当作普通的测试错误。

另外,不要在 __init__ 方法里做太多提前的错误检查。如果有人提供了错误类型的对象,你的代码会在正常情况下失败,并通过正常的方式抛出一个普通的异常。你不需要对对象进行太多的“预筛选”。

19

在unittest模块中,我们可以使用assertRaises来测试当调用某个函数时是否会抛出特定的异常,但这通常适用于类的方法。那么,如何正确地对构造函数进行这样的测试呢?

构造函数本身就是一个可以调用的东西:

self.assertRaises(AssertionError, MyClass, arg1, arg2)

说到这里,我想强调nosklo和S.Lott对参数类型检查的担忧。此外,你不应该用断言来检查函数的参数:断言最有用的地方是作为一种安全检查,只有当你的代码内部出现问题时,它才会被触发。而且,当Python以“优化”-O模式运行时,断言语句会被编译掉。如果一个函数需要对其参数进行某种检查,它应该抛出一个合适的异常。

撰写回答