【问题标题】:How do I replace a class variable for the duration of a single test in Python?如何在 Python 中的单个测试期间替换类变量?
【发布时间】:2015-08-23 18:41:02
【问题描述】:

我正在尝试测试应该自动删除旧项目的缓存类。缓存可以容纳的项目数量由一个“常量”类变量控制,如下所示:

class Cache(dict):
    MAX_ITEMS = 100

出于测试目的,我想在单个测试用例的持续时间内更改该常量。使用unittest.mock.patch 我可以用MagicMock 替换类变量,但这并不是我真正想要做的。我只需要用不同的号码替换它。

有没有一种优雅的方式在 Python 中执行此操作(例如 patch),还是我应该自己在 tearDown 上重置变量?


我使用的是 Python 3.4.3

【问题讨论】:

  • 你可以使用with 语法为测试中的值创建一个有限的范围,这看起来还不错。但是,如果您需要它为每个测试用例在相应的设置/拆卸方法中执行它似乎更好。
  • @Voo 最好有一个像patch 这样的函数,它只是确保在测试后恢复原始值,而不用模拟对象替换它
  • 我认为使用setUptearDown 是可行的方法;如果您不知道另一种方式,那么下一位读者可能也不会!

标签: python unit-testing python-3.x python-unittest


【解决方案1】:

patch 已经可以做到这一点了。试试:

from unittest.mock import patch

class A:
    val = 1

assert A.val == 1
with patch.object(A, "val", "patched_value"):
    assert A.val == "patched_value"

assert A.val == 1

当然你也可以使用patch.object作为装饰器。

【讨论】:

    【解决方案2】:

    Reading the docs 更仔细一点,原来patch 实际上有一个可选参数来控制变量被替换为什么(而不是模拟对象),所以我可以这样做:

    class CacheTest(TestCase):
        @patch("myproject.Cache.MAX_ITEMS", new=3)
        def testCacheTrim(self):
            # ...
    

    或者,正如 Dunes 指出的那样:

    class CacheTest(TestCase):
        @patch.object(Cache, "MAX_ITEMS", new=3)
        def testCacheTrim(self):
            # ...
    

    可以说看起来更漂亮。

    【讨论】:

      【解决方案3】:

      您可以考虑提供一个设置 MAX_ITEMS 的类构造函数。比如:

      class Cache(dict):
          def __init__(self, *args, **kwargs):
              self.MAX_ITEMS = kwargs.get("MAX_ITEMS", 100)  # default value
      
          @classmethod
          def create_with_max(cls, MAX_ITEMS, *args, **kwargs):
              return cls(MAX_ITEMS=MAX_ITEMS, *args, **kwargs)
      
      >>> c = Cache.create_with_max(40)
      >>> c.MAX_ITEMS
      40
      

      这将允许您设置缓存大小(在测试期间或其他情况下)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-03-11
        • 2017-11-13
        • 2019-08-10
        • 2018-12-18
        • 2020-11-20
        • 1970-01-01
        • 2018-12-19
        • 2014-12-08
        相关资源
        最近更新 更多