I have a sample flask application as below
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!"
Also I have a pytest for this
@pytest.fixture
def client():
tester = app.test_client()
yield tester
def test_index():
response = client.get('/')
assert response.status_code == 200
I want to write the test cases for my application.
Whenever I try to test the index ie / or any endpoint it will goto before_request first that it was my application design
Is there a way to skip the before_request in pytest?
So that i can test my functionality whether its working properly or not.
CodePudding user response:
Solution 1
Ideally, you should put conditions inside before_request() on which cases it should be skipped, such as in the docs which is based on the presence of a key in session:
@app.before_request
def load_user():
if "user_id" in session:
g.user = db.session.get(session["user_id"])
If that is done, we can then try to patch those objects in the condition (in the example above is session) to control whether it would be skipped or not.
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
Solution 2
If changing the before_request() is not an option, an alternative solution (not recommended but would work) is to remove the unwanted before_request functions registered in the Flask-app object via its before_request_funcs.
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
...
Output
$ 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
- As you can see, with the patches, the code within
before_request()wasn't executed.
