ForcePilot/backend/test/unit/channels/application/conftest.py

132 lines
3.7 KiB
Python
Raw Normal View History

"""channels application 层单元测试共享 fixture。
提供 application 层被驱动仓储 / 能力端口桩OutboxRepositoryPort /
MessageRepositoryPort / ChannelSessionRepositoryPort /
ChannelAccountRepositoryPort / PairingRepositoryPort /
AuditLogRepositoryPort / ConversationPort / TransactionPort / QueuePort /
ContentReviewRepositoryPort / UserIdentityRepositoryPort /
IdempotencyRepositoryPort / PersistencePort / RealtimeMetricsPort
桩使用 ``AsyncMock()``异步端口/ ``MagicMock()``TransactionPort.begin
为同步方法不实现真实逻辑方法签名以
``yuxi.channels.contract.ports.driven`` 下的 Protocol 为准单文件独有的
helper 应保留在对应测试文件内 testing-guidelines.md
注意``TransactionPort.begin`` 在端口协议中为同步方法返回
TransactionContext ``async with`` 消费因此 ``fake_transaction_port``
使用 ``MagicMock()`` 而非 ``AsyncMock()``避免 ``begin`` 被误生成为协程
"""
from __future__ import annotations
from unittest.mock import AsyncMock, MagicMock
import pytest
@pytest.fixture
def fake_outbox_repo() -> AsyncMock:
"""OutboxRepositoryPort 桩。
预设 ``saveOutboxEntry`` / ``getOutboxEntry`` / ``updateOutboxEntry``
返回 None``listPendingOutboxEntries`` 返回空列表
"""
mock = AsyncMock()
mock.saveOutboxEntry.return_value = None
mock.getOutboxEntry.return_value = None
mock.updateOutboxEntry.return_value = None
mock.listPendingOutboxEntries.return_value = []
return mock
@pytest.fixture
def fake_message_repo() -> AsyncMock:
"""MessageRepositoryPort 桩。"""
return AsyncMock()
@pytest.fixture
def fake_session_repo() -> AsyncMock:
"""ChannelSessionRepositoryPort 桩。"""
return AsyncMock()
@pytest.fixture
def fake_account_repo() -> AsyncMock:
"""ChannelAccountRepositoryPort 桩。"""
return AsyncMock()
@pytest.fixture
def fake_pairing_repo() -> AsyncMock:
"""PairingRepositoryPort 桩。"""
return AsyncMock()
@pytest.fixture
def fake_audit_log_repo() -> AsyncMock:
"""AuditLogRepositoryPort 桩。"""
return AsyncMock()
@pytest.fixture
def fake_conversation_port() -> AsyncMock:
"""ConversationPort 桩。"""
return AsyncMock()
@pytest.fixture
def fake_transaction_port() -> MagicMock:
"""TransactionPort 桩。
``begin`` 为同步方法返回一个 async context manager
``__aenter__`` / ``__aexit__`` / ``commit`` / ``rollback`` 均为
AsyncMock ``async with transaction.begin() as tx:`` 使用
"""
port = MagicMock()
tx_ctx = MagicMock()
tx_ctx.__aenter__ = AsyncMock(return_value=tx_ctx)
tx_ctx.__aexit__ = AsyncMock(return_value=None)
tx_ctx.commit = AsyncMock(return_value=None)
tx_ctx.rollback = AsyncMock(return_value=None)
port.begin.return_value = tx_ctx
return port
@pytest.fixture
def fake_queue_port() -> AsyncMock:
"""QueuePort 桩,``enqueue`` 默认返回 "job-001""""
mock = AsyncMock()
mock.enqueue.return_value = "job-001"
return mock
@pytest.fixture
def fake_content_review_repo() -> AsyncMock:
"""ContentReviewRepositoryPort 桩。"""
return AsyncMock()
@pytest.fixture
def fake_user_identity_repo() -> AsyncMock:
"""UserIdentityRepositoryPort 桩。"""
return AsyncMock()
@pytest.fixture
def fake_idempotency_repo() -> AsyncMock:
"""IdempotencyRepositoryPort 桩。"""
return AsyncMock()
@pytest.fixture
def fake_persistence_port() -> AsyncMock:
"""PersistencePort 桩。"""
return AsyncMock()
@pytest.fixture
def fake_realtime_metrics() -> AsyncMock:
"""RealtimeMetricsPort 桩。"""
return AsyncMock()