python - 模拟装饰器函数以绕过装饰器逻辑
问题描述
我正在尝试为我的代码编写一些单元测试,而这些代码又使用了一个装饰器
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 并完全绕过装饰器逻辑部分。这在 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)
推荐阅读
- php - 没有得到不同的价格 每张图片都得到相同的价格 标题上没有不同的 id
- django - NoReverseMatch:未找到“password_reset_confirm”的反向。'password_reset_confirm' 不是有效的视图函数或模式名称
- python - 如何使用硒单击html中的文本?
- java - 如何在事务达到超时时执行一些操作
- php - 根据用户的类型/角色重定向到不同的视图。使用 Laravel 5.8
- import - 将 Excel 文件数据导入 Alfresco Datalist
- c# - 如何将 C# 字典绑定到 Angular 6 材质中的下拉列表
- wcf-security - 使用 ConfigurationChannelFactory.CreateChannel 时向 WCF 添加请求标头
- ios - UIPageViewController 中的 WKWebView 在滑动时卸载
- android - 为什么在将 Video Uri 转换为 Bytearray 时出现 FileNotFoundException?