从 TestCase 派生一个类会引发两个错误 [英] Deriving a class from TestCase throws two errors
问题描述
我有一些基本的设置/拆卸代码,我想在一大堆单元测试中重用它们.所以我有了创建一些派生类以避免在每个测试类中重复代码的好主意.
I have some basic setup/teardown code that I want to reuse in a whole bunch of unit tests. So I got the bright idea of creating some derived classes to avoid repeating code in every test class.
这样做时,我收到了两个奇怪的错误.一,我无法解决.这是一个无法解决的问题:
In so doing, I received two strange errors. One, I cannot solve. Here is the unsolvable one:
AttributeError: 'TestDesktopRootController' object has no attribute '_testMethodName'
这是我的基类:
import unittest
import twill
import cherrypy
from cherrypy._cpwsgi import CPWSGIApp
class BaseControllerTest(unittest.TestCase):
def __init__(self):
self.controller = None
def setUp(self):
app = cherrypy.Application(self.controller)
wsgi = CPWSGIApp(app)
twill.add_wsgi_intercept('localhost', 8080, lambda : wsgi)
def tearDown(self):
twill.remove_wsgi_intercept('localhost', 8080)
这是我的派生类:
import twill
from base_controller_test import BaseControllerTest
class TestMyController(BaseControllerTest):
def __init__(self, args):
self.controller = MyController()
BaseControllerTest.__init__(self)
def test_root(self):
script = "find 'Contacts'"
twill.execute_string(script, initial_url='http://localhost:8080/')
另一个奇怪的错误是:
TypeError: __init__() takes exactly 1 argument (2 given)
对此的解决方案"是在派生类的 __init__
函数中添加单词args".有什么办法可以避免吗?
The "solution" to that was to add the word "args" to my __init__
function in the derived class. Is there any way to avoid that?
记住,我有两个错误.
推荐答案
这是因为您错误地覆盖了 __init__()
.几乎可以肯定,您根本不想覆盖 __init__()
;你应该在 setUp()
中做所有事情.我已经使用 unittest
超过 10 年了,而且我认为我从未重写过 __init__()
.
It's because you're overriding __init__()
incorrectly. Almost certainly, you don't want to override __init__()
at all; you should do everything in setUp()
. I've been using unittest
for >10 years and I don't think I've ever overridden __init__()
.
但是,如果您确实需要重写 __init__()
,请记住,您无法控制构造函数的调用位置——框架会为您调用它.所以你必须提供一个它可以调用的签名.从源代码 (unittest/case.py
) 来看,该签名是:
However, if you really do need to override __init__()
, remember that you don't control where your constructor is called -- the framework calls it for you. So you have to provide a signature that it can call. From the source code (unittest/case.py
), that signature is:
def __init__(self, methodName='runTest'):
执行此操作的安全方法是接受任何参数并将它们传递给基类.这是一个有效的实现:
The safe way to do this is to accept any arguments and just pass 'em up to the base class. Here is a working implementation:
class BaseTest(unittest.TestCase):
def __init__(self, *args, **kwargs):
unittest.TestCase.__init__(self, *args, **kwargs)
def setUp(self):
print "Base.setUp()"
def tearDown(self):
print "Base.tearDown()"
class TestSomething(BaseTest):
def __init__(self, *args, **kwargs):
BaseTest.__init__(self, *args, **kwargs)
self.controller = object()
def test_silly(self):
self.assertTrue(1+1 == 2)
这篇关于从 TestCase 派生一个类会引发两个错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!