Browse Source

Merge 7177f674e6 into 6df50d40fe

pull/13674/merge
Walancy.S 4 days ago
committed by GitHub
parent
commit
147f1c3a1c
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 118
      tests/test_include_more_routes.py
  2. 131
      tests/test_route_with_multiple_methods.py

118
tests/test_include_more_routes.py

@ -0,0 +1,118 @@
import pytest
from fastapi import APIRouter, FastAPI, Request
from fastapi.responses import JSONResponse
from fastapi.testclient import TestClient
from pydantic import BaseModel
# ======================
# Configuração do app e rotas
# ======================
app = FastAPI()
router = APIRouter()
class Item(BaseModel):
nome: str
quantidade: int
@router.route("/items/", methods=["GET", "POST"])
async def read_items(request: Request):
if request.method == "POST":
try:
dados = await request.json()
item = Item(**dados)
return JSONResponse(
{"message": "Item criado", "item": item.model_dump()}, status_code=201
)
except Exception:
return JSONResponse({"detail": "Erro ao processar JSON"}, status_code=400)
return JSONResponse({"hello": "world"})
app.include_router(router)
client = TestClient(app)
################ Testes
# Testa se a rota GET /items/ retorna a resposta padrão esperada
def test_get_items():
resposta = client.get("/items/")
assert resposta.status_code == 200
assert resposta.json() == {"hello": "world"}
# Testa se a rota POST /items/ aceita e retorna corretamente um JSON válido
def test_post_items():
payload = {"nome": "Caderno", "quantidade": 10}
resposta = client.post("/items/", json=payload)
assert resposta.status_code == 201
assert resposta.json() == {
"message": "Item criado",
"item": {"nome": "Caderno", "quantidade": 10},
}
# Testa se a rota POST /items/ retorna erro ao receber JSON inválido (faltando campo obrigatório)
def test_post_json_invalido():
payload = {"quantidade": 5} # Campo 'nome' está ausente
resposta = client.post("/items/", json=payload)
assert resposta.status_code == 400
assert resposta.json()["detail"] == "Erro ao processar JSON"
# Testa se a rota POST /items/ retorna erro ao receber corpo que não seja JSON
def test_post_com_corpo_nao_json():
resposta = client.post("/items/", content="texto") # Texto cru, não é JSON
assert resposta.status_code == 400
assert resposta.json()["detail"] == "Erro ao processar JSON"
# Testa se a rota POST /items/ aceita headers customizados e responde corretamente
def test_post_com_header_customizado():
headers = {"Custom-Header": "123"}
payload = {"nome": "Caneta", "quantidade": 3}
resposta = client.post("/items/", json=payload, headers=headers)
assert resposta.status_code == 201
assert resposta.json()["item"]["nome"] == "Caneta"
# Testa se métodos não permitidos como PUT são corretamente bloqueados pela API
def test_method_not_allowed():
resposta = client.put("/items/")
assert resposta.status_code == 405 # 405 Method Not Allowed
assert "detail" in resposta.json()
# Testa múltiplos métodos HTTP para a mesma rota usando parametrização
# Verifica se cada método responde com o status esperado
@pytest.mark.parametrize(
"metodo,status_esperado",
[
("GET", 200),
("POST", 201),
("PUT", 405),
("DELETE", 405),
("PATCH", 405),
],
)
def test_varios_metodos(metodo, status_esperado):
payload = {"nome": "Caneta", "quantidade": 1}
resposta = client.request(metodo, "/items/", json=payload)
assert resposta.status_code == status_esperado
# Testa se a resposta da rota GET /items/ contém o header correto de Content-Type (application/json)
def test_headers_da_resposta():
resposta = client.get("/items/")
assert resposta.headers["content-type"].startswith("application/json")
# Testa se a rota GET ignora parâmetros de query (ex: ?busca=algo)
def test_get_com_query_params_ignorados():
resposta = client.get("/items/?busca=algo")
assert resposta.status_code == 200
assert resposta.json() == {"hello": "world"}

131
tests/test_route_with_multiple_methods.py

@ -0,0 +1,131 @@
# https://github.com/fastapi/fastapi/issues/10180
from fastapi import APIRouter, FastAPI
from fastapi.testclient import TestClient
def test_mount_subapp_on_apirouter_should_not_work():
app = FastAPI()
router = APIRouter(prefix="/api")
@router.get("/main")
def main():
return {"msg": "main"}
subapp = FastAPI()
@subapp.get("/sub")
def sub():
return {"msg": "sub"}
# Tentativa de montar subapp no router (não funciona)
router.mount("/subapi", subapp)
app.include_router(router)
client = TestClient(app)
# A rota principal funciona
assert client.get("/api/main").status_code == 200
# A rota da subaplicação NÃO funciona (deveria retornar 404)
assert client.get("/api/subapi/sub").status_code == 404
def test_mount_subapp_on_app_should_work():
app = FastAPI()
router = APIRouter(prefix="/api")
@router.get("/main")
def main():
return {"msg": "main"}
subapp = FastAPI()
@subapp.get("/sub")
def sub():
return {"msg": "sub"}
app.include_router(router)
# Montando corretamente no app principal
app.mount("/api/subapi", subapp)
client = TestClient(app)
# A rota principal funciona
assert client.get("/api/main").status_code == 200
# A rota da subaplicação funciona
assert client.get("/api/subapi/sub").status_code == 200
# Testes adicionais para melhorar cobertura:
def test_mount_multiple_subapps():
"""Testa se é possível montar múltiplas subaplicações"""
app = FastAPI()
# Primeira subaplicação
subapp1 = FastAPI()
@subapp1.get("/test1")
def read_test1():
return {"msg": "test1"}
# Segunda subaplicação
subapp2 = FastAPI()
@subapp2.get("/test2")
def read_test2():
return {"msg": "test2"}
# Montando ambas as subaplicações
app.mount("/sub1", subapp1)
app.mount("/sub2", subapp2)
client = TestClient(app)
# Verifica se ambas as subaplicações funcionam
assert client.get("/sub1/test1").status_code == 200
assert client.get("/sub2/test2").status_code == 200
assert client.get("/sub1/test1").json() == {"msg": "test1"}
assert client.get("/sub2/test2").json() == {"msg": "test2"}
def test_nested_routes():
"""Testa rotas aninhadas em diferentes níveis"""
app = FastAPI()
# Criando routers aninhados
router1 = APIRouter(prefix="/v1")
router2 = APIRouter(prefix="/api")
@router2.get("/deep")
def read_deep():
return {"msg": "deep route"}
# Aninhando os routers
router1.include_router(router2)
app.include_router(router1)
client = TestClient(app)
# Verifica se a rota aninhada funciona
response = client.get("/v1/api/deep")
assert response.status_code == 200
assert response.json() == {"msg": "deep route"}
# Verifica se uma rota inexistente retorna 404
assert client.get("/v1/api/nonexistent").status_code == 404
def test_method_not_allowed():
"""Testa se métodos HTTP não permitidos são tratados corretamente"""
app = FastAPI()
@app.get("/only-get")
def read_only():
return {"msg": "get only"}
client = TestClient(app)
# Verifica se GET funciona
assert client.get("/only-get").status_code == 200
# Verifica se outros métodos retornam 405 (Method Not Allowed)
assert client.post("/only-get").status_code == 405
assert client.put("/only-get").status_code == 405
assert client.delete("/only-get").status_code == 405
Loading…
Cancel
Save