gpt4 book ai didi

Python - 使单元测试独立于具有类变量的类

转载 作者:行者123 更新时间:2023-12-04 21:05:06 27 4
gpt4 key购买 nike

我有一个带有字典的类,用于缓存来自服务器对特定输入的响应。由于这是用于缓存目的,因此将其保存为类变量。

class MyClass:
cache_dict = {}

def get_info_server(self, arg):
if arg not in self.cache_dict:
self.cache_dict[arg] = Client.get_from_server(arg)
return cache_dict[arg]

def do_something(self, arg):
# Do something based on get_info_server(arg)
并且在编写单元测试时,由于字典是类变量,因此值会跨测试用例进行缓存。
测试用例
# Assume that Client is mocked.

def test_caching():
m = MyClass()
m.get_info_server('foo')
m.get_info_server('foo')
mock_client.get_from_server.assert_called_with_once('foo')

def test_do_something():
m = MyClass()
mock_client.get_from_server.return_value = 'bar'
m.do_something('foo') # This internally calls get_info_server('foo')
如果 test_caching首先执行,缓存的值将是一些模拟对象。如果 test_do_something首先执行,然后测试用例被调用一次的断言将失败。
如何使测试彼此独立, 除了直接操作字典 (因为这就像需要对代码的内部工作有深入的了解。如果内部工作稍后发生变化怎么办。我需要验证的是 API 本身,而不是依赖于内部工作)?

最佳答案

您无法避免在此处重置缓存。如果你正在对这个类进行单元测试,那么你的单元测试需要对类的内部工作有深入的了解,所以只需重置缓存。无论如何,如果不调整单元测试,你很少能改变你的类(class)的工作方式。

如果你觉得这仍然会造成维护负担,那么通过添加一个类方法来显式处理缓存:

class MyClass:
cache_dict = {}

@classmethod
def _clear_cache(cls):
# for testing only, hook to clear the class-level cache.
cls.cache_dict.clear()

请注意,我仍然给它起了一个带前导下划线的名称;这不是第 3 方应该调用的方法,它仅用于测试。但是现在您已经集中清除了缓存,让您可以控制它的实现方式。

如果您使用 unittest运行测试的框架,在每个测试前清除缓存 TestCase.setUp() method .如果您使用不同的测试框架,该框架将有一个类似的钩子(Hook)。在每次测试之前清除缓存可确保您始终拥有干净的状态。

请注意您的缓存不是线程安全的,如果您正在与线程并行运行测试,您将在这里遇到问题。因为这也适用于缓存实现本身,所以这可能不是您现在担心的事情。

关于Python - 使单元测试独立于具有类变量的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48173887/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com