| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- """
- 应用层异常单元测试
- 测试应用层异常类的创建、属性和行为。
- """
- import pytest
- from src.application.shared.exceptions import (
- ApplicationException,
- ResourceNotFoundException,
- ValidationException,
- )
- class TestApplicationException:
- """ApplicationException 单元测试"""
-
- def test_create_with_message_only(self):
- """测试仅使用消息创建异常"""
- # Arrange & Act
- exception = ApplicationException("Test error")
-
- # Assert
- assert exception.message == "Test error"
- assert exception.details == {}
- assert str(exception) == "Test error"
-
- def test_create_with_message_and_details(self):
- """测试使用消息和详细信息创建异常"""
- # Arrange
- details = {"key": "value", "code": 123}
-
- # Act
- exception = ApplicationException("Test error", details=details)
-
- # Assert
- assert exception.message == "Test error"
- assert exception.details == details
- assert "Test error" in str(exception)
- assert "Details:" in str(exception)
-
- def test_str_representation(self):
- """测试异常的字符串表示"""
- # Arrange
- exception = ApplicationException(
- "Error occurred",
- details={"reason": "Invalid input"}
- )
-
- # Act
- result = str(exception)
-
- # Assert
- assert "Error occurred" in result
- assert "Details:" in result
- assert "reason" in result
-
- def test_repr_representation(self):
- """测试异常的详细表示"""
- # Arrange
- exception = ApplicationException(
- "Error occurred",
- details={"reason": "Invalid input"}
- )
-
- # Act
- result = repr(exception)
-
- # Assert
- assert "ApplicationException" in result
- assert "message=" in result
- assert "details=" in result
-
- def test_exception_can_be_raised_and_caught(self):
- """测试异常可以被抛出和捕获"""
- # Arrange & Act & Assert
- with pytest.raises(ApplicationException) as exc_info:
- raise ApplicationException("Test error")
-
- assert exc_info.value.message == "Test error"
-
- def test_exception_inherits_from_exception(self):
- """测试异常继承自 Exception"""
- # Arrange
- exception = ApplicationException("Test error")
-
- # Act & Assert
- assert isinstance(exception, Exception)
- class TestResourceNotFoundException:
- """ResourceNotFoundException 单元测试"""
-
- def test_create_with_resource_type_and_id(self):
- """测试使用资源类型和 ID 创建异常"""
- # Arrange & Act
- exception = ResourceNotFoundException(
- resource_type="Document",
- resource_id="doc_123"
- )
-
- # Assert
- assert exception.resource_type == "Document"
- assert exception.resource_id == "doc_123"
- assert "Document" in exception.message
- assert "doc_123" in exception.message
- assert "not found" in exception.message
-
- def test_details_include_resource_info(self):
- """测试详细信息包含资源信息"""
- # Arrange & Act
- exception = ResourceNotFoundException(
- resource_type="KnowledgeBase",
- resource_id="kb_456"
- )
-
- # Assert
- assert exception.details["resource_type"] == "KnowledgeBase"
- assert exception.details["resource_id"] == "kb_456"
-
- def test_create_with_additional_details(self):
- """测试使用额外详细信息创建异常"""
- # Arrange
- additional_details = {"reason": "Database query returned no results"}
-
- # Act
- exception = ResourceNotFoundException(
- resource_type="Document",
- resource_id="doc_789",
- details=additional_details
- )
-
- # Assert
- assert exception.details["resource_type"] == "Document"
- assert exception.details["resource_id"] == "doc_789"
- assert exception.details["reason"] == "Database query returned no results"
-
- def test_exception_message_format(self):
- """测试异常消息格式"""
- # Arrange & Act
- exception = ResourceNotFoundException(
- resource_type="ParsedDocument",
- resource_id="parsed_001"
- )
-
- # Act
- message = exception.message
-
- # Assert
- assert message == "ParsedDocument with id 'parsed_001' not found"
-
- def test_exception_inherits_from_application_exception(self):
- """测试异常继承自 ApplicationException"""
- # Arrange
- exception = ResourceNotFoundException(
- resource_type="Document",
- resource_id="doc_123"
- )
-
- # Act & Assert
- assert isinstance(exception, ApplicationException)
- assert isinstance(exception, Exception)
- class TestValidationException:
- """ValidationException 单元测试"""
-
- def test_create_with_message_only(self):
- """测试仅使用消息创建异常"""
- # Arrange & Act
- exception = ValidationException("Validation failed")
-
- # Assert
- assert exception.message == "Validation failed"
- assert exception.field is None
- assert exception.reason is None
- assert exception.details == {}
-
- def test_create_with_field_and_reason(self):
- """测试使用字段和原因创建异常"""
- # Arrange & Act
- exception = ValidationException(
- message="Invalid content",
- field="content",
- reason="Content cannot be empty"
- )
-
- # Assert
- assert exception.message == "Invalid content"
- assert exception.field == "content"
- assert exception.reason == "Content cannot be empty"
- assert exception.details["field"] == "content"
- assert exception.details["reason"] == "Content cannot be empty"
-
- def test_create_with_field_only(self):
- """测试仅使用字段创建异常"""
- # Arrange & Act
- exception = ValidationException(
- message="Invalid input",
- field="email"
- )
-
- # Assert
- assert exception.field == "email"
- assert exception.reason is None
- assert "field" in exception.details
- assert "reason" not in exception.details
-
- def test_create_with_reason_only(self):
- """测试仅使用原因创建异常"""
- # Arrange & Act
- exception = ValidationException(
- message="Invalid input",
- reason="Must be a positive number"
- )
-
- # Assert
- assert exception.field is None
- assert exception.reason == "Must be a positive number"
- assert "field" not in exception.details
- assert "reason" in exception.details
-
- def test_create_with_additional_details(self):
- """测试使用额外详细信息创建异常"""
- # Arrange
- additional_details = {
- "min_length": 10,
- "max_length": 100,
- "actual_length": 5
- }
-
- # Act
- exception = ValidationException(
- message="Invalid length",
- field="description",
- reason="Length out of range",
- details=additional_details
- )
-
- # Assert
- assert exception.details["field"] == "description"
- assert exception.details["reason"] == "Length out of range"
- assert exception.details["min_length"] == 10
- assert exception.details["max_length"] == 100
- assert exception.details["actual_length"] == 5
-
- def test_exception_inherits_from_application_exception(self):
- """测试异常继承自 ApplicationException"""
- # Arrange
- exception = ValidationException("Validation failed")
-
- # Act & Assert
- assert isinstance(exception, ApplicationException)
- assert isinstance(exception, Exception)
-
- def test_multiple_validation_errors(self):
- """测试多个验证错误"""
- # Arrange
- errors = [
- {"field": "email", "reason": "Invalid format"},
- {"field": "age", "reason": "Must be positive"}
- ]
-
- # Act
- exception = ValidationException(
- message="Multiple validation errors",
- details={"errors": errors}
- )
-
- # Assert
- assert "errors" in exception.details
- assert len(exception.details["errors"]) == 2
|