gpt4 book ai didi

python - 如何对装饰函数进行单元测试?

转载 作者:太空狗 更新时间:2023-10-29 18:08:40 26 4
gpt4 key购买 nike

我最近尝试在单元测试最佳实践方面对自己进行大量培训。其中大部分都非常有道理,但有一点经常被忽视和/或解释不当:一个单元测试修饰函数应该如何?

假设我有这段代码:

def stringify(func):
@wraps(func)
def wrapper(*args):
return str(func(*args))

return wrapper


class A(object):
@stringify
def add_numbers(self, a, b):
"""
Returns the sum of `a` and `b` as a string.
"""
return a + b

我显然可以编写以下测试:

def test_stringify():
@stringify
def func(x):
return x

assert func(42) == "42"

def test_A_add_numbers():
instance = MagicMock(spec=A)
result = A.add_numbers.__wrapped__(instance, 3, 7)
assert result == 10

这给了我 100% 的覆盖率:我知道任何用 stringify() 修饰的函数都会得到字符串形式的结果,而且我知道未修饰的 A.add_numbers() 函数返回其参数的总和。因此,根据传递性,A.add_numbers() 的装饰版本必须返回其参数的总和,作为字符串。一切似乎都很好!

但是我对此并不完全满意:如果我使用另一个装饰器(做其他事情,比如将结果乘以 2 而不是转换为 海峡)。我的函数 A.add_numbers 将不再正确,但测试仍会通过。不太好。

我可以测试 A.add_numbers() 的装饰版本,但我会过度测试,因为我的装饰器已经过单元测试。

感觉好像我在这里遗漏了什么。对装饰函数进行单元测试的好策略是什么?

最佳答案

我最终将装饰器一分为二。因此,与其拥有:

def stringify(func):
@wraps(func)
def wrapper(*args):
return str(func(*args))

return wrapper

我有:

def to_string(value):
return str(value)

def stringify(func):
@wraps(func)
def wrapper(*args):
return to_string(func(*args))

return wrapper

这允许我稍后在测试装饰函数时简单地模拟 to_string

很明显,在这个简单的例子中,它可能看起来有些矫枉过正,但是当用在一个实际做一些复杂或昂贵的事情的装饰器上时(比如打开一个到数据库的连接,或其他),能够模拟它是一个非常好的

关于python - 如何对装饰函数进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30327518/

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