TypeError: object is not callable when instantiating during unit test
TypeError: object is not callable when instantiating during unit test
我有一个 class 在用错误的值实例化时抛出异常,我想编写一个单元测试在给定错误参数时抛出异常。
在 self.assertRaises() 之外实例化一个对象似乎不会导致任何错误,我不明白为什么当我尝试在 assert
中实例化它时它会导致错误
我的 class 看起来像这样:
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()
期望 callable 而不是 called 函数。
您只需提供可调用对象并在没有 ()
的情况下附加参数:
self.assertRaises(ValueError, main.Mark, "X", 5, 32)
或者,您可以使用上下文管理器:
with self.assertRaises(ValueError):
main.Mark("X", 5, 32)
assertRaises
的签名与您的用法不同。参见 documentation Here
您应该为它提供一个可调用对象和调用它时应使用的参数,或者您应该使用 with
语句并照常调用它。
这是一个片段,显示了两种方法:
def test_marks(self):
self.assertRaises(ValueError, main.Mark, "X", 5, 32)
with self.assertRaises(ValueError):
main.Mark(1, "X", 32)
根据您修改后的问题:
你实际上并没有抛出异常,而是在你的代码中捕获了它,所以断言失败了,因为你没有做你期望的事情。测试成功!
现在,如果你想检查异常是否按预期被捕获,你应该测试是否打印了 print 语句:
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"
。您应该将其替换为异常的输出。
我有一个 class 在用错误的值实例化时抛出异常,我想编写一个单元测试在给定错误参数时抛出异常。
在 self.assertRaises() 之外实例化一个对象似乎不会导致任何错误,我不明白为什么当我尝试在 assert
中实例化它时它会导致错误我的 class 看起来像这样:
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()
期望 callable 而不是 called 函数。
您只需提供可调用对象并在没有 ()
的情况下附加参数:
self.assertRaises(ValueError, main.Mark, "X", 5, 32)
或者,您可以使用上下文管理器:
with self.assertRaises(ValueError):
main.Mark("X", 5, 32)
assertRaises
的签名与您的用法不同。参见 documentation Here
您应该为它提供一个可调用对象和调用它时应使用的参数,或者您应该使用 with
语句并照常调用它。
这是一个片段,显示了两种方法:
def test_marks(self):
self.assertRaises(ValueError, main.Mark, "X", 5, 32)
with self.assertRaises(ValueError):
main.Mark(1, "X", 32)
根据您修改后的问题: 你实际上并没有抛出异常,而是在你的代码中捕获了它,所以断言失败了,因为你没有做你期望的事情。测试成功!
现在,如果你想检查异常是否按预期被捕获,你应该测试是否打印了 print 语句:
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"
。您应该将其替换为异常的输出。