【问题标题】:Order of inheritance for setUp()/tearDown() methods for TestCase and mixin classesTestCase 和 mixin 类的 setUp()/tearDown() 方法的继承顺序
【发布时间】:2019-10-30 12:17:11
【问题描述】:

我想知道,当为具有多重继承的类运行 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 没有同样的问题?毕竟,不会使用来自TestsMixinsetUp() 方法并跳过来自TestsBasesetUp() 吗?

我的结论是unittest 模块必须为此工作。有谁知道什么/如何?

提前致谢。

【问题讨论】:

    标签: python unit-testing multiple-inheritance


    【解决方案1】:

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

    在我的示例中,MRO 如下所示:

    对于测试用例 1:

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

    对于TestCase2:

     - 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。

    【讨论】:

      猜你喜欢
      • 2020-01-31
      • 1970-01-01
      • 2016-06-04
      • 2015-12-27
      • 1970-01-01
      • 1970-01-01
      • 2014-03-06
      • 2018-04-10
      • 1970-01-01
      相关资源
      最近更新 更多