0
0
FastapiHow-ToBeginner · 4 min read

How to Mock Database in FastAPI Test: Simple Guide

To mock a database in FastAPI tests, override the database dependency with a test version using app.dependency_overrides. Use an in-memory SQLite database or mock objects to simulate database behavior without affecting the real database.
📐

Syntax

In FastAPI, you mock the database by overriding the dependency that provides the database session. This is done by assigning a test function to app.dependency_overrides[original_dependency]. The test function returns a test database session, often an in-memory SQLite session.

  • app.dependency_overrides: A dictionary to replace dependencies during tests.
  • get_db: The original dependency that yields a database session.
  • override_get_db: Your test function that yields a test database session.
python
from fastapi import FastAPI, Depends
from sqlalchemy.orm import Session

app = FastAPI()

def get_db():
    # Original database session provider
    db = Session()
    try:
        yield db
    finally:
        db.close()

# In tests:

def override_get_db():
    test_db = Session()  # Use test database session here
    try:
        yield test_db
    finally:
        test_db.close()

app.dependency_overrides[get_db] = override_get_db
💻

Example

This example shows how to mock the database in a FastAPI test using an in-memory SQLite database. It overrides the get_db dependency to use the test database, then runs a test client request to verify the mocked database works.

python
from fastapi import FastAPI, Depends
from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, Session
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String

app = FastAPI()

SQLALCHEMY_DATABASE_URL = "sqlite:///:memory:"
engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False})
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()

class User(Base):
    __tablename__ = "users"
    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, index=True)

Base.metadata.create_all(bind=engine)

def get_db():
    db = TestingSessionLocal()
    try:
        yield db
    finally:
        db.close()

@app.post("/users/")
def create_user(name: str, db: Session = Depends(get_db)):
    user = User(name=name)
    db.add(user)
    db.commit()
    db.refresh(user)
    return {"id": user.id, "name": user.name}

# Override dependency for tests

def override_get_db():
    db = TestingSessionLocal()
    try:
        yield db
    finally:
        db.close()

app.dependency_overrides[get_db] = override_get_db

client = TestClient(app)

def test_create_user():
    response = client.post("/users/", params={"name": "Alice"})
    assert response.status_code == 200
    assert response.json()["name"] == "Alice"
Output
PASSED
⚠️

Common Pitfalls

  • Not overriding the dependency: Tests may hit the real database, causing side effects.
  • Using a persistent database for tests: This can cause flaky tests and data pollution.
  • Forgetting to close test sessions: Can lead to connection leaks.
  • Not creating tables in the test database: Leads to errors when querying.
python
## Wrong way: Not overriding dependency
# This hits the real database

# Right way: Override dependency with test DB
app.dependency_overrides[get_db] = override_get_db
📊

Quick Reference

  • Use app.dependency_overrides to replace get_db with a test version.
  • Use an in-memory SQLite database for fast, isolated tests.
  • Always create tables in the test database before running tests.
  • Close test database sessions properly to avoid leaks.
  • Use fastapi.testclient.TestClient to run API tests with mocked DB.

Key Takeaways

Always override the database dependency in FastAPI tests to avoid using the real database.
Use an in-memory SQLite database for fast and isolated test runs.
Create all necessary tables in the test database before running tests.
Close database sessions properly in your test overrides to prevent connection leaks.
Use FastAPI's TestClient to test endpoints with the mocked database.