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.