模拟装饰器函数以绕过装饰器逻辑
Mock a decorator function to bypass decorator logic
我正在尝试为我的代码编写一些单元测试,这些代码又使用装饰器
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)
我正在尝试将装饰函数模拟为 return f 并完全绕过装饰器逻辑部分。这在 Overriding decorator during unit test in python 中有所讨论,但实际上并没有用。
由于装饰器在您定义 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
.)
不过,如果您预计需要测试未修饰的原件,将其保留在自己的(私有)名称下进行测试可能会更简单:无需修补。
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)
我正在尝试为我的代码编写一些单元测试,这些代码又使用装饰器
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)
我正在尝试将装饰函数模拟为 return f 并完全绕过装饰器逻辑部分。这在 Overriding decorator during unit test in python 中有所讨论,但实际上并没有用。
由于装饰器在您定义 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
.)
不过,如果您预计需要测试未修饰的原件,将其保留在自己的(私有)名称下进行测试可能会更简单:无需修补。
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)