【问题标题】:How to skip/block the before_request call in pytest for Python flask application?如何在 Python 烧瓶应用程序的 pytest 中跳过/阻止 before_request 调用?
【发布时间】:2021-11-16 06:55:39
【问题描述】:

我有一个如下示例烧瓶应用程序

from flask import Flask

app = Flask(__name__)

@app.before_request()
def before_request():
   # Something
   if true
       return True
   else
       return False 

@app.route("/")
def index():
    return "Hello World!"

我对此也有一个 pytest

@pytest.fixture
def client():
    tester = app.test_client()
    yield tester

def test_index():
   response = client.get('/')
   assert response.status_code == 200

我想为我的应用程序编写测试用例。

每当我尝试测试索引 ie / 或任何端点时,它都会首先转到 before_request ,这是我的应用程序设计

有没有办法跳过pytest中的before_request?

这样我就可以测试我的功能是否正常工作。

【问题讨论】:

    标签: python flask pytest python-unittest


    【解决方案1】:

    解决方案 1

    理想情况下,您应该将条件放在before_request() 中,在哪些情况下应该跳过它,例如在docs 中,它基于会话中键的存在:

    @app.before_request
    def load_user():
        if "user_id" in session:
            g.user = db.session.get(session["user_id"])
    

    如果这样做了,我们可以尝试修补条件中的那些对象(在上面的示例中是session)来控制是否会被跳过。

    src.py

    from flask import Flask, session
    
    app = Flask(__name__)
    
    
    @app.before_request
    def before_request():
        if "user_id" in session:
            return None  # Let's say we will skip if user_id is present
        print("Before request")
    
    
    @app.route("/")
    def index():
        print("Within index")
        return "Hello World!"
    

    test_src.py

    import pytest
    
    from src import app
    
    
    @pytest.fixture
    def client():
        tester = app.test_client()
        yield tester
    
    
    def test_index_mock_before_request(client, mocker):
        mocker.patch("src.session", {"user_id": None})  # Patch session to include "user_id" so that the before_request would be skipped
    
        response = client.get('/')
        assert response.status_code == 200
    
    
    def test_index(client):
        response = client.get('/')
        assert response.status_code == 200
    

    解决方案 2

    如果更改 before_request() 不是一种选择,另一种解决方案(不推荐但可行)是通过 @ 删除在 Flask-app 对象中注册的不需要的 before_request 函数987654322@.

    src.py

    ...
    # Same as above, just replace the following lines
    
    @app.before_request
    def before_request():
        print("Before request")
    ...
    

    test_src.py

    ...
    # Same as above, just replace the following lines
    
    def test_index_mock_before_request(client, mocker):
        mocker.patch.object(app, "before_request_funcs", {})  # Remove all registered before_request functions so that they wouldn't be run
    
        response = client.get('/')
        assert response.status_code == 200
    ...
    

    输出

    $ pytest -q -rP
    ..                                                                                            [100%]
    ============================================== PASSES ===============================================
    __________________________________ test_index_mock_before_request ___________________________________
    --------------------------------------- Captured stdout call ----------------------------------------
    Within index
    ____________________________________________ test_index _____________________________________________
    --------------------------------------- Captured stdout call ----------------------------------------
    Before request
    Within index
    2 passed in 0.14s
    
    • 如您所见,通过补丁,before_request() 中的代码未执行。

    【讨论】:

    • 感谢您的回复。你能告诉我嘲笑者的装置吗?
    • 哦,我没有提供有关该信息的信息。你必须运行pip install pytest-mockpypi.org/project/pytest-mock
    猜你喜欢
    • 2013-11-01
    • 1970-01-01
    • 2018-01-22
    • 2019-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多