我有一个很好的基础测试类,它扩展了django测试用例和另一个类:
class MyTestCase(TestCase, TestFreshProvisionedEachTest):
现在一切正常,除了为了使它工作,我们必须修补(使用Foord的模拟库)中间件中的几个函数。
我的想法是,这样做会很好:
@patch('spotlight.middleware.extract_host_name', new=lambda host_name:
TEST_DOMAIN)
@patch('spotlight.middleware.extract_host_key', new=lambda host_key:
company_name_to_db(TEST_DOMAIN))
class MyTestCase(TestCase, TestFreshProvisionedEachTest):
但是它似乎不起作用,子类的方法没有修补。 我当时认为可以有办法做一些像
这样的事情MyTestCase = patch(MyTestCase, 'spotlight.middleware.extract_host_name', new=lambda host_name: TEST_DOMAIN)
但这也是不可能的。
有没有办法避免这种重复并在超类上做补丁 哪个修补了所有子类方法?
答案 0 :(得分:1)
最好使用元类,因为它比手动应用装饰器更容易处理测试用例的继承。沿着这些方向的东西(我没有测试它,但你应该得到这个想法):
class TestMeta(type(TestCase)):
def patch_method(cls, meth):
raise NotImplementedError
def __new__(mcls, name, bases, dct):
to_patch = []
for methname, meth in dct.items():
if methname.startswith('test') and callable(meth):
to_patch.append(methname)
cls = super().__new__(mcls, name, bases, dct)
for methname in to_patch:
meth = getattr(cls, methname)
meth = cls.patch_method(meth)
setattr(cls, methname, meth)
return cls
class PatchedTestCase(TestCase, metaclass=TestMeta):
@classmethod
def patch_method(cls, meth):
meth = patch('spotlight.middleware.extract_host_name',
new=lambda host_name: TEST_DOMAIN)(meth)
meth = patch('spotlight.middleware.extract_host_key',
new=lambda host_key: company_name_to_db(TEST_DOMAIN))(meth)
return meth
class MyTestCase(PatchedTestCase, TestFreshProvisionedEachTest):
...
使用此方法,将修补PatchedTestCase
的所有子类的所有方法。您还可以使用不同的patch_method
实现来定义其他基类。