简体   繁体   English

如何在Python中单个测试的持续时间内替换类变量?

[英]How do I replace a class variable for the duration of a single test in Python?

I'm trying to test a cache class where old items should be automatically deleted. 我正在尝试测试一个缓存类,其中应该自动删除旧项。 The amount of items the cache can hold is controlled by a "constant" class variable like this: 缓存可以容纳的项目数量由“常量”类变量控制,如下所示:

class Cache(dict):
    MAX_ITEMS = 100

For testing purposes I would like to change that constant for the duration of a single test case. 出于测试目的,我想在单个测试用例的持续时间内更改该常量。 Using unittest.mock.patch I could replace the class variable with a MagicMock but that's not really what I'm trying to do. 使用unittest.mock.patch我可以用MagicMock替换类变量,但这不是我想要做的。 I just need to replace it with a different number. 我只需要用不同的号码替换它。

Is there an elegant way to do this in Python (like patch ), or should I just reset the variable myself on tearDown ? 有没有一种优雅的方法在Python中执行此操作(如patch ),或者我应该在tearDown自己重置变量?


I'm using Python 3.4.3 我正在使用Python 3.4.3

patch can do this already. 补丁可以做到这一点。 try: 尝试:

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

Of course you can use patch.object as a decorator as well. 当然你也可以使用patch.object作为装饰器。

Reading the docs more carefully, it turns out patch actually has an optional argument that controls what the variable is replaced by (instead of a mock object), so I can do this: 更仔细地阅读文档 ,事实证明patch实际上有一个可选参数来控制变量被替换的(而不是模拟对象),所以我可以这样做:

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

Or, as Dunes pointed out: 或者,正如Dunes指出的那样:

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

Which arguably looks prettier. 这可以说看起来更漂亮。

You could consider providing a class constructor that sets MAX_ITEMS. 您可以考虑提供一个设置MAX_ITEMS的类构造函数。 Something like: 就像是:

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

This would allow you to set the cache size (during testing or otherwise) 这将允许您设置缓存大小(在测试期间或其他)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM