Как правильно исправить асинхронную функцию для модульных тестов в PytestPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Как правильно исправить асинхронную функцию для модульных тестов в Pytest

Сообщение Anonymous »

Я кодирую приложение FASTAPI с асинхронными функциями. My issue is, I can't mock properly async function with the mocker.patch from pytest-mock nor with AsyncMock from unittest.

The issue is, I can't test this function in the file test/unit/services/auth_test.py:

Код: Выделить всё

from typing import Optional
from src.Exceptions.jwt_token_exceptions import (
CREDENTIALS_EXCEPTION,
)
from src.models import User
from src.security.password import verify_password
from src.services.crud_user import get_user_by_login_with_validity_check
from src.utils.db import SessionDep

async def authenticate_user(
session: SessionDep,
username: str,
password: str,
) -> Optional[User]:
user = await get_user_by_login_with_validity_check(session, username)
if not user:
raise CREDENTIALS_EXCEPTION
is_correct_password = await verify_password(password, user.hashed_password)
if is_correct_password is not True:
raise CREDENTIALS_EXCEPTION
user.set_last_login_date()
await session.commit()
return user
< /code>
Так что мне нужно издеваться над этими функциями (сеанс уже высмеивается): < /p>
[list]
[*] get_user_by_login_with_validity_check
[*]

Код: Выделить всё

verify_password


[/list]
Попытка теста:

Код: Выделить всё

from typing import Optional

import pytest
from unittest.mock import AsyncMock
from src.models import User
from src.services.auth import authenticate_user

PLAIN_PASSWORD = "password"
HASHED_PASSWORD = "hash"
LOGIN = "User"
EMAIL = "user@gmail.com"

def get_user_mock(mocker, return_value: Optional[User]):
return mocker.patch(
"src.services.crud_user.get_user_by_login_with_validity_check",
new=AsyncMock(return_value=return_value),
)

def verify_password_mock(mocker, return_value: bool):
return mocker.patch(
"src.security.password.verify_password",
new=AsyncMock(return_value=return_value),
)

def session_mock(mocker):
mock: AsyncMock = mocker.AsyncMock()
mock.commit.side_effect = lambda: None
return mock

def get_user():
return User(login=LOGIN, email=EMAIL, hashed_password=HASHED_PASSWORD)

@pytest.mark.asyncio
async def test_authenticate_user_success(mocker):
user = get_user()
mock_session = session_mock(mocker)
mock_get_user = get_user_mock(mocker, user)
mock_verify_password = verify_password_mock(mocker,True)

results = await authenticate_user(mock_session, LOGIN, PLAIN_PASSWORD)
< /code>
Журналы ошибок: < /p>
test\unit\service\auth_test.py:37 (test_authenticate_user_success)
mocker = 

@pytest.mark.asyncio
async def test_authenticate_user_success(mocker):
user = get_user()
mock_session = session_mock(mocker)
mock_get_user = get_user_mock(mocker, user)
mock_verify_password = verify_password_mock(mocker,True)

>       results = await authenticate_user(mock_session, LOGIN, PLAIN_PASSWORD)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

test\unit\service\auth_test.py:45:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
src\services\auth.py:19: in authenticate_user
user = await get_user_by_login_with_validity_check(session, username)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

session = , login = 'User'

async def get_user_by_login_with_validity_check(
session: SessionDep, login: str
) -> Optional[User]:
user: User = await get_user_by_login(session, login)
if user is None:
raise USER_DOESNT_EXISTS
>       if user.deleted:
^^^^^^^^^^^^
E       AttributeError: 'coroutine' object has no attribute 'deleted'

src\services\crud_user.py:57: AttributeError
sys:1: RuntimeWarning: coroutine 'AsyncMockMixin._execute_mock_call' was never awaited
Похоже, что мой патч не существует ... потому что он входит в функцию вместо использования Mock
Я ожидаю правильно использовать макет и просто работать как ожидалось:/

Подробнее здесь: https://stackoverflow.com/questions/796 ... -in-pytest
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»