TypeError:在单元测试期间实例化对象时不可调用



我有一个类,当用错误的值实例化时会抛出异常,我想写一个单元测试,当给定错误的参数时会引发异常。

实例化self之外的对象。assertRaises((似乎不会导致任何错误,当我试图在assert 中实例化它时,我不明白为什么它会导致错误

我的课是这样的:

class Mark:
def __init__(self, a, b, c):
try:
self.a = a
self.b = int(b)
self.c = int(c)
except ValueError:
print(e)

我的测试是这样的:

import unittest
import main

class Test(unittest.TestCase):
def test_marks(self):
self.assertRaises(ValueError, main.Mark("X", 5, 32))
self.assertRaises(ValueError, main.Mark(1, "X", 32))
self.assertRaises(ValueError, main.Mark(1, 5, "X"))

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

但我得到了:

(base) ➜  Code Python3 test.py
E
======================================================================
ERROR: test_marks (__main__.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Code/test.py", line 12, in test_marks
self.assertRaises(ValueError, main.Mark("X", 5, 32))
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/unittest/case.py", line 733, in assertRaises
return context.handle('assertRaises', args, kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/unittest/case.py", line 201, in handle
callable_obj(*args, **kwargs)
TypeError: 'Mark' object is not callable
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (errors=1)

你知道如果我想测试这个应该怎么做吗?

assertRaises的签名与您的用法不同。请参阅此处的文档

您应该为它提供一个可调用的和它应该使用的参数,或者您应该使用with语句并像往常一样调用它。

下面是一个片段,展示了两种方法:

def test_marks(self):
self.assertRaises(ValueError, main.Mark, "X", 5, 32)
with self.assertRaises(ValueError):
main.Mark(1, "X", 32)

根据您编辑的问题:实际上,您并没有抛出异常,而是在代码中捕获它,因此断言失败,因为您没有按照预期进行操作。测试成功!

现在,如果你想检查异常是否如预期的那样被捕获,你应该测试打印语句是否被打印:

import contextlib
import io
import unittest
import main
class Test(unittest.TestCase):
def test_marks(self):
with contextlib.redirect_stdout(io.StringIO()) as f:
main.Mark(1, 2, 3)
output = f.getvalue().strip()
assert output == 'I am an exception'

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

我们在这里所做的是将标准输出重定向到一个简单的文本流,然后调用您的方法,捕获输出(剥离它以删除任何未知的空白(,并检查输出的字符串是否与我们预期的相同。在我的情况下,我只打印"I am an exception"。您应该将其替换为异常的输出。

assertRaises()需要一个可调用的函数,而不是一个被调用的函数。

您只需给出可调用的并附加不带():的参数

self.assertRaises(ValueError, main.Mark, "X", 5, 32)

或者,您可以使用上下文管理器:

with self.assertRaises(ValueError):
main.Mark("X", 5, 32)

最新更新