ForcePilot/backend/test/unit/channel/startup/test_channel_container.py
Kris 6c95dc006a test: 新增渠道模块全链路单元测试用例与目录结构
完成渠道模块的单元测试目录搭建,新增多个领域模型、端口、中间件、事件、服务以及基础设施层的单元测试文件,同时补充了conftest.py的环境变量配置,完善测试基础环境。
2026-05-30 21:55:35 +08:00

132 lines
4.4 KiB
Python

from __future__ import annotations
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from yuxi.channel.container import ChannelContainer, _InfraBundle, _WorkerBundle
from yuxi.channel.domain.service.pipeline import Pipeline
class TestChannelContainer:
@pytest.fixture
def mock_pipeline(self):
pipeline = MagicMock(spec=Pipeline)
pipeline.middlewares = []
return pipeline
@pytest.fixture
def mock_container(self, mock_pipeline):
return ChannelContainer(
pipeline=mock_pipeline,
inbound_service=MagicMock(),
dispatch_service=MagicMock(),
delivery_service=MagicMock(),
session_resolver=MagicMock(),
binding_service=MagicMock(),
config_service=MagicMock(),
auth_service=MagicMock(),
channel_config=MagicMock(),
worker_pool=MagicMock(),
outbox_worker=MagicMock(),
session_factory=MagicMock(),
)
@pytest.mark.asyncio
async def test_shutdown_with_none_services(self, mock_pipeline):
container = ChannelContainer(pipeline=mock_pipeline)
await container.shutdown()
@pytest.mark.asyncio
async def test_shutdown_closes_adapters(self, mock_container):
adapter = AsyncMock()
mock_container.adapters = {"web": adapter}
await mock_container.shutdown()
adapter.close.assert_awaited_once()
@pytest.mark.asyncio
async def test_shutdown_stops_worker_pool(self, mock_container):
await mock_container.shutdown()
mock_container.worker_pool.stop.assert_awaited_once()
@pytest.mark.asyncio
async def test_shutdown_stops_outbox_worker(self, mock_container):
await mock_container.shutdown()
mock_container.outbox_worker.stop.assert_awaited_once()
@pytest.mark.asyncio
async def test_shutdown_stops_sse_endpoint(self, mock_container):
sse = AsyncMock()
mock_container.sse_endpoint = sse
await mock_container.shutdown()
sse.stop.assert_awaited_once()
sse.broadcast_shutdown.assert_awaited_once()
@pytest.mark.asyncio
async def test_shutdown_stops_ws_manager(self, mock_container):
ws = AsyncMock()
mock_container.ws_manager = ws
await mock_container.shutdown()
ws.stop_all.assert_awaited_once()
@pytest.mark.asyncio
async def test_shutdown_closes_redis(self, mock_container):
redis = AsyncMock()
mock_container.redis = redis
await mock_container.shutdown()
redis.aclose.assert_awaited_once()
@pytest.mark.asyncio
async def test_shutdown_publishes_gateway_shutdown(self, mock_container):
publisher = AsyncMock()
mock_container.event_publisher = publisher
await mock_container.shutdown()
publisher.publish.assert_awaited_once()
@pytest.mark.asyncio
async def test_shutdown_safe_exception_handling(self, mock_container):
mock_container.worker_pool.stop.side_effect = Exception("pool error")
await mock_container.shutdown()
@pytest.mark.asyncio
async def test_shutdown_pubsub_subscriber(self, mock_container):
pubsub = AsyncMock()
mock_container.pubsub_subscriber = pubsub
await mock_container.shutdown()
pubsub.stop.assert_awaited_once()
class TestInfraBundle:
def test_creation(self):
infra = _InfraBundle(
queue_port=MagicMock(),
event_publisher=MagicMock(),
content_filter=MagicMock(),
config_reload=MagicMock(),
cache_port=MagicMock(),
rate_limit_port=MagicMock(),
bot_loop_guard=MagicMock(),
circuit_breaker=MagicMock(),
metrics=MagicMock(),
signature_verifier=MagicMock(),
)
assert infra.queue_port is not None
class TestWorkerBundle:
def test_creation(self):
workers = _WorkerBundle(
dispatch_service=MagicMock(),
binding_service=MagicMock(),
config_service=MagicMock(),
worker_pool=MagicMock(),
outbox_worker=MagicMock(),
session_factory=MagicMock(),
binding_repo=MagicMock(),
session_repo=MagicMock(),
outbox_repo=MagicMock(),
message_repo=MagicMock(),
message_log_repo=MagicMock(),
)
assert workers.dispatch_service is not None