Overrides के साथ Dependencies की Testing¶
🌐 एआई और मनुष्यों द्वारा किया गया अनुवाद
यह अनुवाद मनुष्यों के मार्गदर्शन में एआई द्वारा किया गया है। 🤝
इसमें मूल अर्थ को गलत समझने या अप्राकृतिक लगने आदि जैसी गलतियाँ हो सकती हैं। 🤖
आप हमें एआई LLM को बेहतर मार्गदर्शन करने में मदद करके इस अनुवाद को बेहतर बना सकते हैं।
Testing के दौरान dependencies को override करना¶
कुछ scenarios होते हैं जहाँ आप testing के दौरान किसी dependency को override करना चाह सकते हैं।
आप नहीं चाहते कि original dependency चले (और न ही उसकी कोई sub-dependencies चलें)।
इसके बजाय, आप एक अलग dependency देना चाहते हैं जो केवल tests के दौरान इस्तेमाल होगी (संभवतः केवल कुछ खास tests में), और वह एक ऐसा value देगी जिसे वहाँ इस्तेमाल किया जा सके जहाँ original dependency का value इस्तेमाल किया जाता था।
Use cases: external service¶
एक उदाहरण यह हो सकता है कि आपके पास एक external authentication provider हो जिसे आपको call करना हो।
आप उसे एक token भेजते हैं और वह एक authenticated user लौटाता है।
यह provider आपसे प्रति request शुल्क ले सकता है, और इसे call करने में tests के लिए एक fixed mock user रखने की तुलना में कुछ अतिरिक्त समय लग सकता है।
आप शायद external provider को एक बार test करना चाहेंगे, लेकिन हर चलने वाले test के लिए उसे call करना जरूरी नहीं होगा।
इस मामले में, आप उस dependency को override कर सकते हैं जो उस provider को call करती है, और अपनी tests के लिए एक custom dependency इस्तेमाल कर सकते हैं जो एक mock user लौटाती है।
app.dependency_overrides attribute का उपयोग करें¶
इन मामलों के लिए, आपकी FastAPI application में एक attribute app.dependency_overrides होता है, यह एक simple dict है।
Testing के लिए किसी dependency को override करने के लिए, आप key के रूप में original dependency (एक function) रखते हैं, और value के रूप में अपना dependency override (दूसरा function) रखते हैं।
और फिर FastAPI original dependency की बजाय उस override को call करेगा।
from typing import Annotated
from fastapi import Depends, FastAPI
from fastapi.testclient import TestClient
app = FastAPI()
async def common_parameters(q: str | None = None, skip: int = 0, limit: int = 100):
return {"q": q, "skip": skip, "limit": limit}
@app.get("/items/")
async def read_items(commons: Annotated[dict, Depends(common_parameters)]):
return {"message": "Hello Items!", "params": commons}
@app.get("/users/")
async def read_users(commons: Annotated[dict, Depends(common_parameters)]):
return {"message": "Hello Users!", "params": commons}
client = TestClient(app)
async def override_dependency(q: str | None = None):
return {"q": q, "skip": 5, "limit": 10}
app.dependency_overrides[common_parameters] = override_dependency
def test_override_in_items():
response = client.get("/items/")
assert response.status_code == 200
assert response.json() == {
"message": "Hello Items!",
"params": {"q": None, "skip": 5, "limit": 10},
}
def test_override_in_items_with_q():
response = client.get("/items/?q=foo")
assert response.status_code == 200
assert response.json() == {
"message": "Hello Items!",
"params": {"q": "foo", "skip": 5, "limit": 10},
}
def test_override_in_items_with_params():
response = client.get("/items/?q=foo&skip=100&limit=200")
assert response.status_code == 200
assert response.json() == {
"message": "Hello Items!",
"params": {"q": "foo", "skip": 5, "limit": 10},
}
🤓 Other versions and variants
Tip
Prefer to use the Annotated version if possible.
from fastapi import Depends, FastAPI
from fastapi.testclient import TestClient
app = FastAPI()
async def common_parameters(q: str | None = None, skip: int = 0, limit: int = 100):
return {"q": q, "skip": skip, "limit": limit}
@app.get("/items/")
async def read_items(commons: dict = Depends(common_parameters)):
return {"message": "Hello Items!", "params": commons}
@app.get("/users/")
async def read_users(commons: dict = Depends(common_parameters)):
return {"message": "Hello Users!", "params": commons}
client = TestClient(app)
async def override_dependency(q: str | None = None):
return {"q": q, "skip": 5, "limit": 10}
app.dependency_overrides[common_parameters] = override_dependency
def test_override_in_items():
response = client.get("/items/")
assert response.status_code == 200
assert response.json() == {
"message": "Hello Items!",
"params": {"q": None, "skip": 5, "limit": 10},
}
def test_override_in_items_with_q():
response = client.get("/items/?q=foo")
assert response.status_code == 200
assert response.json() == {
"message": "Hello Items!",
"params": {"q": "foo", "skip": 5, "limit": 10},
}
def test_override_in_items_with_params():
response = client.get("/items/?q=foo&skip=100&limit=200")
assert response.status_code == 200
assert response.json() == {
"message": "Hello Items!",
"params": {"q": "foo", "skip": 5, "limit": 10},
}
सुझाव
आप अपनी FastAPI application में कहीं भी इस्तेमाल की गई dependency के लिए dependency override set कर सकते हैं।
Original dependency किसी path operation function, किसी path operation decorator (जब आप return value का उपयोग नहीं करते), किसी .include_router() call आदि में इस्तेमाल हो सकती है।
FastAPI फिर भी उसे override कर पाएगा।
फिर आप app.dependency_overrides को एक खाली dict पर set करके अपने overrides reset कर सकते हैं (उन्हें हटा सकते हैं):
app.dependency_overrides = {}
सुझाव
यदि आप किसी dependency को केवल कुछ tests के दौरान override करना चाहते हैं, तो आप test की शुरुआत में (test function के अंदर) override set कर सकते हैं और अंत में (test function के अंत में) उसे reset कर सकते हैं।