gpt4 book ai didi

python - pytest-monkeypatch 装饰器(不使用模拟/补丁)

转载 作者:行者123 更新时间:2023-12-04 16:44:58 25 4
gpt4 key购买 nike

我正在使用带有monkeypatch 固定装置的pytest 编写一些测试。遵循规则,我导入类和方法以从它们正在使用的模块中模拟出来,而不是从源中模拟出来。

我正在为其编写测试的应用程序是使用标准环境的 Google App Engine 应用程序。因此我必须使用 python 2.7,我使用的实际版本是 2.7.15 - pytest 版本是 3.5.0

到目前为止,一切都运行良好,但在尝试模拟装饰器函数时遇到了问题。

从顶部开始。在一个名为 decorators.py 的 py 文件中,包含所有 auth 装饰器,包括我想要模拟的装饰器。有问题的装饰器是一个模块函数,而不是类的一部分。

def user_login_required(handler):
def is_authenticated(self, *args, **kwargs):
u = self.auth.get_user_by_session()
if u.access == '' or u.access is None:
# return the response
self.redirect('/admin', permanent=True)
else:
return handler(self, *args, **kwargs)
return is_authenticated

装饰器应用于 web 请求函数。在名为 handlers (handlers.UserDetails) 的文件夹中名为 UserDetails.py 的文件中的基本示例
from decorators import user_login_required

class UserDetailsHandler(BaseHandler):
@user_login_required
def get(self):
# Do web stuff, return html, etc

在测试模块中,我正在设置这样的测试:
from handlers.UserDetails import user_login_required

@pytest.mark.parametrize('params', get_params, ids=get_ids)
def test_post(self, params, monkeypatch):

monkeypatch.setattr(user_login_required, mock_user_login_required_func)

问题在于monkeypatch 不允许我将单个函数作为目标。它希望目标是一个类,然后是要替换的方法名称,然后是模拟方法....
monkeypatch.setattr(WouldBeClass, "user_login_required", mock_user_login_required_func)

我试图调整代码,看看我是否可以通过改变装饰器的导入和使用方式来解决它:
import decorators

class UserDetailsHandler(BaseHandler):
@decorators.user_login_required
def get(self):
# Do web stuff, return html, etc

然后在测试中我尝试像这样修补函数名称.....
from handlers.UserDetails import decorators

@pytest.mark.parametrize('params', get_params, ids=get_ids)
def test_post(self, params, monkeypatch):

monkeypatch.setattr(decorators, "user_login_required" , mock_user_login_required_func)

虽然这段代码没有抛出任何错误,但当我逐步完成测试时,代码永远不会进入 mock_user_login_required_func。它总是进入实时装饰器。

我究竟做错了什么?这是一个试图对一般装饰器进行猴子修补的问题,或者模块中的单独功能是否可以不被修补?

最佳答案

看起来这里的快速答案只是移动您的 Handler 导入,使其在补丁之后发生。装饰器和被装饰的函数必须在单独的模块中,这样在你修补它之前,python 不会执行装饰器。

from decorators import user_login_required

@pytest.mark.parametrize('params', get_params, ids=get_ids)
def test_post(self, params, monkeypatch):

monkeypatch.setattr(decorators, "user_login_required" , mock_user_login_required_func)
from handlers.UserDetails import UserDetailsHandler

您可能会发现使用内置 unittest.mock 模块中的 patch 函数更容易完成此操作。

关于python - pytest-monkeypatch 装饰器(不使用模拟/补丁),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51466579/

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