I have the following flask app route:
# routes.py
from flask import jsonify
from app.utils.db import db_connection, db_query
@api.route("/some/route", methods=["GET"])
@auth
def get_data_for_some_route(**kwargs) -> List[Dict]:
# connect to db
db_client = db_connection()
# Query db for data
data = db.query(db_client, GET_STUFF)
# parse the data example
parsed_data = data[0]
return jsonify(parsed_data), 200
How can I write a pytest for this route, but mock the db connection and query results?
# test_routes.py
import pytest
from fixtures import SOME_ROUTE_JSON_DATA
mock_token = "12345"
def test_get_data_for_some_route(mocker, client):
querystring1 = 'Hello'
querystring2 = 'World'
# Mock db query function
mocked_db_query = mocker.patch('app.utils.database.db_connection')
mocked_db_query.return_value = loads(SOME_ROUTE_JSON_DATA)
# Call the route
response = client.get(
f"/some_route",
headers={"Authorization": f"{mock_token}"}
)
# assert response.json is some value I expect it to be
I'm a little confused how to mock values within the route. So the database connection can be ignored and I can also say 'this is what the return data will be in this case, continue on testing the function pretending that is what the data is.'
To patch a function you need to provide the full path to the function being patched. In your case both db_connection
and db_query
need to be patched. You could do something like this:
import pytest
from app import app
# Sample JSON data for testing
SOME_ROUTE_JSON_DATA = '{"key": "value"}'
# Mock token for authorization
mock_token = "12345"
@pytest.fixture
def client():
"""Create a test client using Flask app context."""
with app.test_client() as client:
yield client
def test_get_data_for_some_route(mocker, client):
# Mock db_connection and db_query functions
mocked_db_connection = mocker.patch("app.utils.database.db_connection")
mocked_db_query = mocker.patch("app.utils.database.db_query")
# Set the return value for db_query to the sample JSON data
mocked_db_query.return_value = json.loads(SOME_ROUTE_JSON_DATA)
# Call the route with mocked data
response = client.get(
"/some_route",
headers={"Authorization": f"Bearer {mock_token}"}
)
# Assert response status code
assert response.status_code == 200
# Assert response JSON data
expected_data = {"key": "value"} # Define the expected JSON response
assert response.get_json() == expected_data
# Assert that db_connection and db_query were called with expected arguments
mocked_db_connection.assert_called_once()
mocked_db_query.assert_called_once_with(mocked_db_connection.return_value, "GET_STUFF")