TestCase和mixin类的setUp()/tearDown()方法的继承顺序



我想知道,当为具有多重继承的类运行setUp()/tearDown()方法时,unittest做了什么特别的事情。

举以下例子:

import unittest
class Foo:
def __init__(self, foo):
self._foo = foo
@property
def foo(self):
return self._foo
class TestsBase(unittest.TestCase):
def setUp(self):
super().setUp()
self.base_value = 1
class TestsMixin:
def setUp(self):
super().setUp()
self.expected_value = 1

class TestCase1(TestsMixin, TestsBase):
def test_base_value_is_equal_to_expected_value(self):
foo = Foo(self.base_value)
self.assertEqual(foo.foo, self.expected_value)

class TestCase2(TestsBase, TestsMixin):
def test_base_value_is_equal_to_expected_value(self):
foo = Foo(self.base_value)
self.assertEqual(foo.foo, self.expected_value)

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

当运行此代码时,TestCase1类测试将成功,而TestCase2测试将失败,说明AttributeError: 'TestCase2' object has no attribute 'expected_value'

现在,我明白了MRO是如何工作的,我也明白了为什么会出现这个错误,但让我困惑的是,为什么TestCase1没有同样的问题?毕竟,难道不应该使用TestsMixin中的setUp()方法,跳过TestsBase中的setUp()吗?

我的结论是unittest模块必须为此做些什么。有人知道什么/怎么做吗?

提前谢谢。

我找到了自己问题的答案。最后,一切都归结为MRO。

例如,MRO看起来是这样的:

对于测试用例1:

- TestCase1
- TestsMixin
- TestsBase
- unittest.TestCase
- object

对于测试用例2:

- TestCase2
- TestsBase
- unittest.TestCase
- TestsMixin
- object

问题是,unittest.TestCase在其自己的setUp()调用中不调用super().setUp()

原因很简单,object没有setUp()

unittest.TestCase()中,通过在其setUp()例程中添加以下代码,可以很容易地绕过这一点:

def setUp(self):
parent = super()
if hasattr(parent, 'setUp'):
parent.setUp()

它是有效的。但这说明了另一个问题。现在,我的TestsMixin停止为工作,原因完全相同。我必须在每一个可能的mixin中添加这个保护代码,这并不理想。

因此,更好的解决方案是保持原样,并确保在您的基础之前列出您的mixin

相关内容

  • 没有找到相关文章

最新更新