- 新增多个业务域的__init__.py模块文件,规范包导出结构 - 调整多个DTO文件的导入路径,统一模块组织方式 - 移除测试文件中多余的空行与导入语句 - 优化部分业务模块的包层级划分
151 lines
6.5 KiB
Python
151 lines
6.5 KiB
Python
"""infrastructure/container.py 装配容器单元测试。
|
||
|
||
覆盖 ``yuxi.scheduler.infrastructure.container`` 模块的两个 factory 函数:
|
||
- ``create_scheduler_service``:api 进程请求级 factory(handler_registry=None)
|
||
- ``create_worker_scheduler_service``:worker 进程请求级 factory(完整 runtime)
|
||
|
||
验证装配结果 ``SchedulerService`` 实例的依赖注入正确性。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from unittest.mock import MagicMock, patch
|
||
|
||
import pytest
|
||
from yuxi.scheduler.framework.runtime import HandlerRegistry, RuntimeServices
|
||
from yuxi.scheduler.infrastructure.container import (
|
||
SchedulerService,
|
||
create_scheduler_service,
|
||
create_worker_scheduler_service,
|
||
)
|
||
|
||
pytestmark = pytest.mark.unit
|
||
|
||
|
||
@pytest.fixture
|
||
def db_session() -> MagicMock:
|
||
"""提供 MagicMock 模拟 AsyncSession。"""
|
||
return MagicMock()
|
||
|
||
|
||
# ─── create_scheduler_service ─────────────────────────────────────────────
|
||
|
||
|
||
@pytest.mark.unit
|
||
class TestCreateSchedulerService:
|
||
def test_returns_scheduler_service_instance(self, db_session: MagicMock):
|
||
# Arrange & Act
|
||
with patch("yuxi.scheduler.infrastructure.container.app_config"):
|
||
service = create_scheduler_service(db_session)
|
||
# Assert
|
||
assert isinstance(service, SchedulerService)
|
||
|
||
def test_handler_registry_is_none(self, db_session: MagicMock):
|
||
# Arrange & Act - api 进程 handler_registry=None
|
||
with patch("yuxi.scheduler.infrastructure.container.app_config"):
|
||
service = create_scheduler_service(db_session)
|
||
# Assert
|
||
assert service._runtime.handler_registry is None
|
||
|
||
def test_arq_pool_defaults_to_none(self, db_session: MagicMock):
|
||
with patch("yuxi.scheduler.infrastructure.container.app_config"):
|
||
service = create_scheduler_service(db_session)
|
||
assert service._runtime.arq_pool is None
|
||
|
||
def test_arq_pool_passed_through(self, db_session: MagicMock):
|
||
# Arrange
|
||
pool = MagicMock()
|
||
# Act
|
||
with patch("yuxi.scheduler.infrastructure.container.app_config"):
|
||
service = create_scheduler_service(db_session, arq_pool=pool)
|
||
# Assert
|
||
assert service._runtime.arq_pool is pool
|
||
|
||
def test_repos_injected(self, db_session: MagicMock):
|
||
with patch("yuxi.scheduler.infrastructure.container.app_config"):
|
||
service = create_scheduler_service(db_session)
|
||
# Assert - 4 个仓储实例被注入
|
||
assert service._repos.task is not None
|
||
assert service._repos.run_log is not None
|
||
assert service._repos.run_log_daily is not None
|
||
assert service._repos.idempotency is not None
|
||
|
||
def test_tx_port_injected(self, db_session: MagicMock):
|
||
with patch("yuxi.scheduler.infrastructure.container.app_config"):
|
||
service = create_scheduler_service(db_session)
|
||
assert service._tx_port is not None
|
||
|
||
def test_config_injected(self, db_session: MagicMock):
|
||
with patch("yuxi.scheduler.infrastructure.container.app_config") as mock_config:
|
||
service = create_scheduler_service(db_session)
|
||
assert service._runtime.config is mock_config
|
||
|
||
|
||
# ─── create_worker_scheduler_service ──────────────────────────────────────
|
||
|
||
|
||
@pytest.mark.unit
|
||
class TestCreateWorkerSchedulerService:
|
||
def test_returns_scheduler_service_instance(self, db_session: MagicMock):
|
||
# Arrange
|
||
registry = HandlerRegistry()
|
||
pool = MagicMock()
|
||
# Act
|
||
with patch("yuxi.scheduler.infrastructure.container.app_config"):
|
||
service = create_worker_scheduler_service(db_session, handler_registry=registry, arq_pool=pool)
|
||
# Assert
|
||
assert isinstance(service, SchedulerService)
|
||
|
||
def test_handler_registry_injected(self, db_session: MagicMock):
|
||
registry = HandlerRegistry()
|
||
pool = MagicMock()
|
||
with patch("yuxi.scheduler.infrastructure.container.app_config"):
|
||
service = create_worker_scheduler_service(db_session, handler_registry=registry, arq_pool=pool)
|
||
assert service._runtime.handler_registry is registry
|
||
|
||
def test_arq_pool_injected(self, db_session: MagicMock):
|
||
registry = HandlerRegistry()
|
||
pool = MagicMock()
|
||
with patch("yuxi.scheduler.infrastructure.container.app_config"):
|
||
service = create_worker_scheduler_service(db_session, handler_registry=registry, arq_pool=pool)
|
||
assert service._runtime.arq_pool is pool
|
||
|
||
def test_repos_injected(self, db_session: MagicMock):
|
||
registry = HandlerRegistry()
|
||
pool = MagicMock()
|
||
with patch("yuxi.scheduler.infrastructure.container.app_config"):
|
||
service = create_worker_scheduler_service(db_session, handler_registry=registry, arq_pool=pool)
|
||
assert service._repos.task is not None
|
||
assert service._repos.run_log is not None
|
||
assert service._repos.run_log_daily is not None
|
||
assert service._repos.idempotency is not None
|
||
|
||
def test_tx_port_injected(self, db_session: MagicMock):
|
||
registry = HandlerRegistry()
|
||
pool = MagicMock()
|
||
with patch("yuxi.scheduler.infrastructure.container.app_config"):
|
||
service = create_worker_scheduler_service(db_session, handler_registry=registry, arq_pool=pool)
|
||
assert service._tx_port is not None
|
||
|
||
|
||
# ─── RuntimeServices 装配 ─────────────────────────────────────────────────
|
||
|
||
|
||
@pytest.mark.unit
|
||
class TestRuntimeServicesAssembly:
|
||
def test_api_runtime_has_none_registry(self, db_session: MagicMock):
|
||
with patch("yuxi.scheduler.infrastructure.container.app_config"):
|
||
service = create_scheduler_service(db_session)
|
||
# Assert - RuntimeServices dataclass 字段正确
|
||
assert isinstance(service._runtime, RuntimeServices)
|
||
assert service._runtime.handler_registry is None
|
||
|
||
def test_worker_runtime_has_registry_and_pool(self, db_session: MagicMock):
|
||
registry = HandlerRegistry()
|
||
pool = MagicMock()
|
||
with patch("yuxi.scheduler.infrastructure.container.app_config"):
|
||
service = create_worker_scheduler_service(db_session, handler_registry=registry, arq_pool=pool)
|
||
assert isinstance(service._runtime, RuntimeServices)
|
||
assert service._runtime.handler_registry is registry
|
||
assert service._runtime.arq_pool is pool
|