mirror of
https://github.com/xlorepdarkhelm/numinar-coding-project.git
synced 2026-09-06 01:08:25 -04:00
118 lines
3.7 KiB
Python
118 lines
3.7 KiB
Python
"""Test cases for the SQL module in the Numinar coding project backend.
|
|
|
|
This primarily focuses on testing the sessionize decorator to ensure it correctly
|
|
manages database sessions for asynchronous functions.i
|
|
"""
|
|
|
|
from typing import Any
|
|
from typing import AsyncGenerator
|
|
from unittest.mock import AsyncMock
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
import pytest_asyncio
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from backend.db import sessionize
|
|
|
|
|
|
@pytest_asyncio.fixture
|
|
async def mock_async_sessionmaker() -> AsyncGenerator[AsyncMock, None]:
|
|
"""Fixture to mock the async sessionmaker for testing sessionize decorator.
|
|
|
|
Yields:
|
|
AsyncMock: A mocked async sessionmaker that returns a mocked AsyncSession.
|
|
"""
|
|
with patch("backend.db.async_sessionmaker") as mock_sessionmaker:
|
|
mock_session: AsyncMock = AsyncMock(spec=AsyncSession)
|
|
mock_sessionmaker.return_value = AsyncMock(return_value=mock_session)
|
|
yield mock_sessionmaker
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_sessionize_decorator_with_no_session(
|
|
mock_async_sessionmaker: AsyncMock,
|
|
) -> None:
|
|
"""Test the sessionize decorator when no session is provided.
|
|
|
|
Verifies that the decorator creates a new session and passes it to the function,
|
|
and that the function executes correctly.
|
|
"""
|
|
|
|
@sessionize
|
|
async def test_func(session: AsyncSession | None = None) -> str:
|
|
setattr(test_func, "session", session) # noqa: B010
|
|
return "success"
|
|
|
|
result: str = await test_func()
|
|
assert result == "success"
|
|
assert test_func.session is not None # type: ignore
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_sessionize_decorator_with_session(
|
|
mock_async_sessionmaker: AsyncMock,
|
|
) -> None:
|
|
"""Test the sessionize decorator when a session is provided.
|
|
|
|
Verifies that the decorator uses the provided session without creating a new one,
|
|
and that the function executes correctly.
|
|
"""
|
|
|
|
@sessionize
|
|
async def test_func(session: AsyncSession | None = None) -> str:
|
|
setattr(test_func, "session", session) # noqa: B010
|
|
return "success"
|
|
|
|
mock_session: AsyncMock = AsyncMock(spec=AsyncSession)
|
|
result: str = await test_func(session=mock_session)
|
|
assert result == "success"
|
|
assert mock_session is test_func.session # type: ignore
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_sessionize_decorator_error_handling(
|
|
mock_async_sessionmaker: AsyncMock,
|
|
) -> None:
|
|
"""Test the sessionize decorator's error handling.
|
|
|
|
Verifies that the decorator properly handles exceptions raised by the decorated
|
|
function and ensures the session is created when none is provided.
|
|
"""
|
|
|
|
@sessionize
|
|
async def test_func(session: AsyncSession) -> None:
|
|
setattr(test_func, "session", session) # noqa: B010
|
|
raise ValueError("Test error")
|
|
|
|
with pytest.raises(ValueError, match="Test error"):
|
|
await test_func()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.parametrize(
|
|
"func_return_value",
|
|
["result1", 42, None],
|
|
ids=["string", "integer", "none"],
|
|
)
|
|
async def test_sessionize_decorator_return_types(
|
|
mock_async_sessionmaker: AsyncMock, func_return_value: Any
|
|
) -> None:
|
|
"""Test the sessionize decorator with different return types.
|
|
|
|
Verifies that the decorator correctly handles various return types from the
|
|
decorated function.
|
|
|
|
Args:
|
|
mock_async_sessionmaker: Mocked async sessionmaker.
|
|
func_return_value: The value to be returned by the test function.
|
|
"""
|
|
|
|
@sessionize
|
|
async def test_func(session: AsyncSession) -> Any:
|
|
setattr(test_func, "session", session) # noqa: B010
|
|
return func_return_value
|
|
|
|
result: Any = await test_func()
|
|
assert result == func_return_value
|