pythonasyncioapiasyncfastapiframeworkjsonjson-schemaopenapiopenapi3pydanticpython-typespython3redocreststarletteswaggerswagger-uiuvicornweb
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
3.9 KiB
118 lines
3.9 KiB
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"}
|
|
|