最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

python - AsyncMock not working when mocked using SQLAlchemy in FastAPI - Stack Overflow

programmeradmin2浏览0评论

I'm testing a FastAPI service that queries a database using SQLAlchemy's async execution. However, when I mock the database query, execute().scalars().all() returns an empty list instead of the expected [1, 2, 3].

async def retrieve_relevant_docs(session: AsyncSession, query: str, top_k: int):
    results = await session.execute(select(Document.id).limit(top_k))
    print("debug results", vars(results))  # Debugging
    document_ids = list(await results.scalars())
    print("document_ids", document_ids)  # Debugging
    return document_ids
import pytest
from unittest.mock import AsyncMock

@pytest.mark.asyncio
async def test_retrieve_relevant_docs():
    mock_session = AsyncMock()
    mock_execute = AsyncMock()

    # Attempt to mock scalars() to return values
    mock_scalars_selected = AsyncMock()
    mock_scalars_selected.scalars.return_value.all.return_value = [1, 2, 3]

    mock_execute.side_effect = [mock_scalars_selected, mock_scalars_selected]
    mock_session.execute = mock_execute  # Mocking session.execute

    # Calling the function
    document_ids = await retrieve_relevant_docs(mock_session, "test query", top_k=3)
    
    # Debugging
    print("Final document_ids:", document_ids)  

    assert document_ids == [1, 2, 3]  # This fails because document_ids is []

Observed Behavior: results.scalars().all() unexpectedly returns [], even though I attempted to mock it. Debugging vars(results) shows _mock_side_effect = None, suggesting the mock isn't working as expected. Expected Behavior: document_ids should contain [1, 2, 3], matching the mocked return value

What I've Tried:

  • Explicitly setting scalars().all().return_value = [1, 2, 3].
  • Checking vars(results) for missing attributes.
  • Ensuring mock_execute.side_effect is properly assigned.
  • Calling await session.execute(...).scalars().all() instead of wrapping it in list().

Extra Debug logs:

selected_ids_result debug results {'_mock_return_value': sentinel.DEFAULT, '_mock_parent': None, '_mock_name': None, '_mock_new_name': '()', '_mock_new_parent': , '_mock_sealed': False, '_spec_class': None, '_spec_set': None, '_spec_signature': None, '_mock_methods': None, '_spec_asyncs': [], '_mock_children': {'scalars': , 'str': }, '_mock_wraps': None, '_mock_delegate': None, '_mock_called': False, '_mock_call_args': None, '_mock_call_count': 0, '_mock_call_args_list': [], '_mock_mock_calls': [call.str(), call.scalars(), call.scalars().all()], 'method_calls': [call.scalars()], '_mock_unsafe': False, '_mock_side_effect': None, '_is_coroutine': <object object at 0x0000029C06E16A30>, '_mock_await_count': 0, '_mock_await_args': None, '_mock_await_args_list': [], 'code': , 'str': } document_ids [] AssertionError: assert [] == [1, 2, 3]

What is the correct way to mock SQLAlchemy's async execution (session.execute().scalars().all()) in a FastAPI test using AsyncMock?

发布评论

评论列表(0)

  1. 暂无评论