""" 应用层接口单元测试 测试命令处理器和查询处理器协议的实现。 """ import pytest from typing import List from src.application.shared.interfaces import CommandHandler, QueryHandler # 测试用的命令和查询类(不以Test开头避免被pytest收集) class SampleCommand: """示例命令""" def __init__(self, value: str): self.value = value class SampleQuery: """示例查询""" def __init__(self, filter_value: str): self.filter_value = filter_value class SampleResult: """示例结果""" def __init__(self, data: str): self.data = data # 具体的处理器实现 class ConcreteCommandHandler: """具体的命令处理器实现""" async def handle(self, command: SampleCommand) -> str: """处理示例命令""" return f"Processed: {command.value}" class ConcreteQueryHandler: """具体的查询处理器实现""" async def handle(self, query: SampleQuery) -> List[SampleResult]: """处理示例查询""" return [SampleResult(f"Result for: {query.filter_value}")] class TestCommandHandlerProtocol: """CommandHandler 协议测试""" @pytest.mark.asyncio async def test_concrete_handler_implements_protocol(self): """测试具体处理器实现协议""" # Arrange handler = ConcreteCommandHandler() command = SampleCommand("test_value") # Act result = await handler.handle(command) # Assert assert result == "Processed: test_value" @pytest.mark.asyncio async def test_handler_can_be_used_as_protocol(self): """测试处理器可以作为协议使用""" # Arrange handler: CommandHandler[SampleCommand, str] = ConcreteCommandHandler() command = SampleCommand("protocol_test") # Act result = await handler.handle(command) # Assert assert "protocol_test" in result def test_protocol_has_handle_method(self): """测试协议有 handle 方法""" # Arrange handler = ConcreteCommandHandler() # Act & Assert assert hasattr(handler, 'handle') assert callable(handler.handle) @pytest.mark.asyncio async def test_handler_with_different_return_type(self): """测试处理器可以返回不同类型""" # Arrange class IntCommandHandler: async def handle(self, command: SampleCommand) -> int: return len(command.value) handler: CommandHandler[SampleCommand, int] = IntCommandHandler() command = SampleCommand("12345") # Act result = await handler.handle(command) # Assert assert result == 5 assert isinstance(result, int) class TestQueryHandlerProtocol: """QueryHandler 协议测试""" @pytest.mark.asyncio async def test_concrete_handler_implements_protocol(self): """测试具体处理器实现协议""" # Arrange handler = ConcreteQueryHandler() query = SampleQuery("test_filter") # Act results = await handler.handle(query) # Assert assert len(results) == 1 assert results[0].data == "Result for: test_filter" @pytest.mark.asyncio async def test_handler_can_be_used_as_protocol(self): """测试处理器可以作为协议使用""" # Arrange handler: QueryHandler[SampleQuery, List[SampleResult]] = ConcreteQueryHandler() query = SampleQuery("protocol_query") # Act results = await handler.handle(query) # Assert assert len(results) > 0 assert "protocol_query" in results[0].data def test_protocol_has_handle_method(self): """测试协议有 handle 方法""" # Arrange handler = ConcreteQueryHandler() # Act & Assert assert hasattr(handler, 'handle') assert callable(handler.handle) @pytest.mark.asyncio async def test_handler_with_empty_results(self): """测试处理器可以返回空结果""" # Arrange class EmptyQueryHandler: async def handle(self, query: SampleQuery) -> List[SampleResult]: return [] handler: QueryHandler[SampleQuery, List[SampleResult]] = EmptyQueryHandler() query = SampleQuery("no_results") # Act results = await handler.handle(query) # Assert assert results == [] assert isinstance(results, list) @pytest.mark.asyncio async def test_handler_with_dict_return_type(self): """测试处理器可以返回字典类型""" # Arrange class DictQueryHandler: async def handle(self, query: SampleQuery) -> dict: return {"filter": query.filter_value, "count": 10} handler: QueryHandler[SampleQuery, dict] = DictQueryHandler() query = SampleQuery("dict_test") # Act result = await handler.handle(query) # Assert assert isinstance(result, dict) assert result["filter"] == "dict_test" assert result["count"] == 10 class TestProtocolTypeHints: """协议类型提示测试""" def test_command_handler_accepts_generic_types(self): """测试命令处理器接受泛型类型""" # Arrange & Act handler: CommandHandler[SampleCommand, str] = ConcreteCommandHandler() # Assert assert handler is not None def test_query_handler_accepts_generic_types(self): """测试查询处理器接受泛型类型""" # Arrange & Act handler: QueryHandler[SampleQuery, List[SampleResult]] = ConcreteQueryHandler() # Assert assert handler is not None @pytest.mark.asyncio async def test_handlers_can_be_composed(self): """测试处理器可以组合使用""" # Arrange command_handler: CommandHandler[SampleCommand, str] = ConcreteCommandHandler() query_handler: QueryHandler[SampleQuery, List[SampleResult]] = ConcreteQueryHandler() # Act command_result = await command_handler.handle(SampleCommand("compose_test")) query_result = await query_handler.handle(SampleQuery("compose_test")) # Assert assert "compose_test" in command_result assert len(query_result) > 0