我正在尝试为我的代码编写一些单元测试,这些代码又使用装饰器
import unittest
from unittest.mock import patch
from functools import wraps
def decorator(f):
@wraps(f)
def decorated(x):
return f(x+1)
return decorated
@decorator
def get_value(x):
return x
class MyTestCase(unittest.TestCase):
@patch('file.decorator', lambda f: f)
def test_something(self):
result = get_value(1)
self.assertEqual(1, result)
我正在尝试模拟装饰函数以仅返回f并完全绕过装饰器逻辑部分。这在Overriding decorator during unit test in python中已经讨论过了,但实际上没有用。
答案 0 :(得分:2)
由于装饰器在定义get_value
后立即运行,因此模拟装饰器为时已晚。但是,您可以做的(因为您使用过functools.wraps
)本身就是模拟get_value
,并以某种方式使用了get_value.__wrapped__
(原始功能)。像
@patch('tmp.get_value', get_value.__wrapped__)
def test_something(self):
result = get_value(1)
self.assertEqual(1, result)
(在这种情况下,我将经过上述更改的原始代码放在tmp.py
中,并以python3 -munittest tmp.py
的身份运行,因此我对引用tmp.get_value
进行了修补。)< / p>
但是,如果您预计需要测试未修饰的原件,则将其保留为自己的(专用)名称进行测试可能会更简单:无需打补丁。
import unittest
from functools import wraps
def decorator(f):
@wraps(f)
def decorated(x):
return f(x+1)
return decorated
def _get_value(x):
return x
get_value = decorator(_get_value)
class MyTestCase(unittest.TestCase):
def test_something(self):
result = _get_value(1)
self.assertEqual(1, result)