我有一个使用Flask公开某些端点的python应用程序。另外,我正在使用fixture
来捕获未处理的异常并返回自定义响应。这是一个示例代码:
from flask import make_response, Blueprint
root = Blueprint("main", __name__)
@root.errorhandler(Exception)
def custom_error_handler(error):
#do other things here
return make_response({"status": "failure", "error": str(error)}), 500
@root.route("/my_url", methods=["POST"])
def my_url_method():
#do other thins
return make_response(...), 200
我想进行测试以确保能正常工作。因此,为了模拟发生未处理的异常,我尝试使用简单引发异常的函数来模拟my_url method
:
from unittest.mock import patch
from flask import Flask
@pytest.fixture
def client(monkeypatch):
app = Flask(__name__, instance_relative_config=True)
app.register_blueprint(root)
app.config["TESTING"] = True
return app.test_client()
def test_exception(client):
with patch("[file_link].my_url_method", side_effect=Exception("an error")):
response = client.post("my_url")
assert response.status_code == 500
但是断言失败。该方法可以正确执行,不会引发任何异常,并返回200作为状态代码。
我认为问题在于调用方法throw flask时没有应用模拟。但是我不知道如何解决。
答案 0 :(得分:0)
我找到了解决方案。它不是最优雅的,但可以。 使用装饰器修补测试有效,因为在创建烧瓶上下文之前应用了修补:
@patch("[file_link].my_url_method", side_effect=Exception("an error")
def test_exception(client):
#some code here
弄清楚这一点,这给了我一个线索,那就是问题取决于烧瓶的初始化和pytest夹具的创建。
但是,这样做会干扰flask上下文的创建,并且无法正确应用应用于每个模拟方法的装饰器。
因此,我没有进行“传统模拟”,而是简单地更新了烧瓶引用以获取必须在请求中调用的功能:
def mocked_function(**args):
raise Exception(MOCKED_EXCEPTION_MESSAGE)
def test_exception(client):
client.application.view_functions["main.my_url_method"] = mocked_function
为每个测试创建的client
固定装置,因此它不会干扰套件中的其余测试。