I’m working on a FastAPI application and am trying to write some tests for one of my routes. My testing environment cannot make calls to external services. My goal is just to test the parsing of the service’s response, creation of log data, etc. The route I am testing calls a function that interacts with the external service, and I want to mock this function to return a predefined response. I’ve tried using pytest’s monkeypatching, but I can’t seem to get it to work.
Here is my project structure:
root
├── routes
│ └── my_route.py
├── services
│ └── my_service.py
├── tests
│ └── test_routes_mocked.py
└── main.py
FastAPI App (main.py)
import os
from fastapi import FastAPI
app = FastAPI(title="API", docs_url="/")
app.include_router(my_route.router)
FastAPI Route (routes/my_route.py)
from fastapi import APIRouter, Depends
from models import MyRequestModel, MyResponseModel
from services.my_service import process_request
router = APIRouter()
@router.post("/process", response_model=MyResponseModel)
async def my_route(request: MyRequestModel):
response = await process_request(request)
# Other logic here that parses the response and builds a response object
return parsed_response
Function to be Mocked (services/my_service.py)
async def process_request(request: MyRequestModel):
# This function returns the call to the external service
result = external_service_call(request)
return result
Test Case (tests/test_routes_mocked.py)
import pytest
from fastapi.testclient import TestClient
from main import app
from services.my_service import process_request
client = TestClient(app)
mock_response_data = {
"data": "mocked response"
}
@pytest.fixture
def mock_process_request(monkeypatch):
async def mock_process(request):
return mock_response_data
monkeypatch.setattr("services.my_service.process_request", mock_process)
def test_my_route(mock_process_request):
request_data = {
"param1": "value1"
}
response = client.post("/process", json=request_data)
assert response.status_code == 200
assert response.json() == mock_response_data
When I run the test, the process_request
function is not being mocked correctly and the original function is still being called. I am wondering how can I properly mock the process_request
function within my FastAPI route?I basically just want to override a single function’s response, just for testing. Any guidance or examples would be greatly appreciated!
I also tried using unittest.mock
to patch the function, but that did not seem to work either