使用unittest.assertRaises
时遇到了一个奇怪的问题。执行下面的代码时,我得到以下输出:
E
======================================================================
ERROR: testAssertRaises (__main__.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\home\python_test\src\derived.py", line 29, in testAssertRaises
self.assertRaises(MyError, self.raiser.raiseMyError)
File "C:\Programme\Python26\lib\unittest.py", line 336, in failUnlessRaises
callableObj(*args, **kwargs)
File "C:\home\python_test\src\derived.py", line 15, in raiseMyError
raise MyError("My message")
MyError: 'My message'
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (errors=1)
引发了正确的异常,但测试失败了!如果我抓住BaseError
测试成功了。
不知怎的,这似乎是unittest无法看到MyError
异常类的范围问题。有人可以解释一下吗?有一些解决方法吗?
我正在测试以下Python代码,这是一个通过类名动态构造对象的实现。
这是基本模块“bases.py”:
class BaseClass(object):
@staticmethod
def get(className):
module = __import__("derived", globals(), locals(), [className])
theClass = getattr(module, className)
return theClass()
class BaseError(Exception):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return repr(self.msg)
这是要测试的模块,“derived.py”:
import unittest
from bases import BaseError
from bases import BaseClass
class MyErrorRaiser(BaseClass):
def raiseMyError(self):
raise MyError("My message")
class MyError(BaseError):
'''
'''
class Test(unittest.TestCase):
def setUp(self):
self.raiser = BaseClass.get("MyErrorRaiser")
def testAssertRaises(self):
self.assertRaises(MyError, self.raiser.raiseMyError)
if __name__ == "__main__":
unittest.main()
答案 0 :(得分:2)
作为mentioned,问题是模块 __ main __ 和派生的不是同一个;这个答案是关于你如何解决这个问题的。
不要混合模块代码和脚本代码。开始将if __name__ == "__main__"
代码视为 hack 。 (它有时候仍然非常方便,我经常使用它进行调试等,但将视为一个黑客,所以你总是会轻微地思考它。)然后运行的新脚本一切都很简单(从不导入):
#!/usr/bin/env python
import derived
import sys
sys.exit(derived.main(sys.argv[1:]))
或根据个人喜好存在各种差异。只需确保添加derived.main即可执行您想要的操作。
我还看到另一个不太常见的黑客,在derived.py的顶部:
import sys
if __name__ == "__main__":
import derived # import the same module under its "correct" name
sys.exit(derived.main(sys.argv[1:]))
虽然在解析相同的代码两次时浪费了,但这在交换中是独立的。
答案 1 :(得分:1)
运行derived.py时,它将作为__main__
模块运行(因为您直接运行它而不是导入它)。稍后显式导入时,会创建另一个模块副本,这次是名称derived
。因此__main__.MyError
与derived.MyError
不同,并且未捕获异常。
答案 2 :(得分:0)
问题可能是你的BaseClass.get()
方法正在返回另一个类。顺便说一下,这种方法本身很可怕,我想知道你为什么要这样做。