Тема: юніт тест на pytest для FastAPI апки
Всім привіт, пробую писати юніт тести на pytest для апки FastAPI і стикнувся з незрозумілою проблемою - отримую невірний код відповіді коли не авторизований.
(якшо шо, то інший юніт тест працює коректно)
функціонал для авторизації:
@app.post("/login")
async def login(request: Request, token: str = Form(...), db: Session = Depends(get_db)):
logging.basicConfig(level = logging.INFO)
logging.info("post /login")
users = get_users(db)
if users:
logging.debug(f"debug /login - users count: {len(users)}")
else:
logging.debug(f"debug /login - Error! users is null")
authenticated_user = None
for user in users:
if pbkdf2_sha256.verify(token, user.token):
authenticated_user = user
break
if authenticated_user:
user_description = authenticated_user.description
logging.info('debug 1111')
#data = {"logout_url": app.url_path_for('logout'),}
data = {
"checkmark_url": app.url_path_for('checkmark'),
"checkmark_negative_url": app.url_path_for('checkmark_negative'),
"api_requests_url": app.url_path_for('api_requests'),
"mapping_url": app.url_path_for('mapping'),
"schedule_list_url": app.url_path_for('schedule_list'),
"fetch_data_to_csv_route_url": app.url_path_for('fetch_data_to_csv_route'),
"datasource_url": app.url_path_for('datasource'),
"secret_tokens_url": app.url_path_for('secret_tokens'),
"home_url": app.url_path_for('home'),
"logout_url": app.url_path_for('logout'),
}
response = templates.TemplateResponse('dashboard.html', {
"request": request,
"description": user_description,
"current_user_id": authenticated_user.id,
"current_user_isadmin": authenticated_user.isadmin,
"current_user": authenticated_user,
"data": data
}), 200
#return response
logging.info('debug 1114')
user_data = {"sub": "token", "id": authenticated_user.id, "description": user_description, "isadmin": authenticated_user.isadmin, "scopes": ["read", "write"]}
token_jwt = create_jwt_token(user_data)
response.set_cookie("token", token_jwt)
logging.info('debug 1115')
return response
else:
response = templates.TemplateResponse('login.html', {
"request": request,
"messages": messages
}), 401
return response
@app.get("/login", name="login", response_class=HTMLResponse)
def login_form(request: Request, next: str = "", current_user: SecretToken = Depends(get_current_user)):
if current_user is not None:
logging.info('debug login get - current_user is not None')
if next:
response = RedirectResponse(url=next)
else:
data = {"logout_url": app.url_path_for('logout'),}
response = templates.TemplateResponse('dashboard.html', {"request": request, "current_user": current_user, "data": data})
return response
else:
messages = ['please authenticate']
logging.basicConfig(level = logging.INFO)
logging.info("get /login")
logging.info('debug login get - current_user is None')
logging.info(f'debug login get - request: {str(request)}')
now = datetime.now()
logging.info(f'debug login get - now: {now}')
return templates.TemplateResponse('login.html', {"request": request, "messages": messages}), 401
сам юніт тест:
@pytest.mark.asyncio
async def test_login_wrong_token(client):
"""
Test if the login view returns the correct response (401 Unauthorized)
when an incorrect token is provided.
"""
rv = client.post('/login', data={'token': 'wrong_token'})
assert rv.status_code == 401, f"Expected status code 401, but got {rv.status_code}"
print("Test passed: The login view returned the correct response (401 Unauthorized) when an incorrect token was provided.")
результат:
mycode1 | ============================= test session starts ==============================
mycode1 | platform linux -- Python 3.10.11, pytest-8.0.0, pluggy-1.4.0
mycode1 | rootdir: /var/www/app
mycode1 | plugins: anyio-4.2.0, asyncio-0.23.5
mycode1 | asyncio: mode=strict
mycode1 | collected 5 items
mycode1 |
mycode1 | test_app.py FF.FF [100%]
mycode1 |
mycode1 | =================================== FAILURES ===================================
mycode1 | ____________________________ test_login_wrong_token ____________________________
mycode1 |
mycode1 | client = <starlette.testclient.TestClient object at 0x7fcedb6abc70>
mycode1 |
mycode1 | @pytest.mark.asyncio
mycode1 | async def test_login_wrong_token(client):
mycode1 | """
mycode1 | Test if the login view returns the correct response (401 Unauthorized)
mycode1 | when an incorrect token is provided.
mycode1 | """
mycode1 | rv = client.post('/login', data={'token': 'wrong_token'})
mycode1 | > assert rv.status_code == 401, f"Expected status code 401, but got {rv.status_code}"
mycode1 | E AssertionError: Expected status code 401, but got 200
mycode1 | E assert 200 == 401
mycode1 | E + where 200 = <Response [200 OK]>.status_code
mycode1 |
mycode1 | test_app.py:61: AssertionError
Повинна повертатися помилка з кодом 401, а повертається чомусь 200 (ок).
Не розумію чому. Може комусь збоку явно видно де моя помилка.