| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- """
- 共享领域异常单元测试
- 测试领域异常类型的创建和行为。
- """
- import pytest
- from src.domain.shared.exceptions import (
- BusinessRuleViolationException,
- DomainException,
- DomainValidationException,
- EntityNotFoundException,
- InvalidValueException,
- )
- class TestDomainException:
- """DomainException 基类单元测试"""
-
- def test_create_domain_exception_with_message(self):
- """测试使用消息创建领域异常"""
- # Act
- exception = DomainException("Something went wrong")
-
- # Assert
- assert exception.message == "Something went wrong"
- assert exception.details == {}
- assert str(exception) == "Something went wrong"
-
- def test_create_domain_exception_with_message_and_details(self):
- """测试使用消息和详细信息创建领域异常"""
- # Arrange
- details = {"field": "name", "value": "invalid"}
-
- # Act
- exception = DomainException("Invalid input", details)
-
- # Assert
- assert exception.message == "Invalid input"
- assert exception.details == details
- assert "details:" in str(exception)
-
- def test_domain_exception_repr(self):
- """测试领域异常的详细表示"""
- # Arrange
- exception = DomainException("Test error", {"key": "value"})
-
- # Act
- repr_str = repr(exception)
-
- # Assert
- assert "DomainException" in repr_str
- assert "Test error" in repr_str
- assert "key" in repr_str
-
- def test_domain_exception_can_be_raised(self):
- """测试领域异常可以被抛出和捕获"""
- # Act & Assert
- with pytest.raises(DomainException) as exc_info:
- raise DomainException("Test error")
-
- assert exc_info.value.message == "Test error"
- class TestInvalidValueException:
- """InvalidValueException 单元测试"""
-
- def test_create_invalid_value_exception(self):
- """测试创建无效值异常"""
- # Act
- exception = InvalidValueException(
- field_name="email",
- invalid_value="invalid-email",
- reason="Email format is invalid"
- )
-
- # Assert
- assert exception.field_name == "email"
- assert exception.invalid_value == "invalid-email"
- assert exception.reason == "Email format is invalid"
- assert "email" in exception.message
- assert "Email format is invalid" in exception.message
-
- def test_invalid_value_exception_details(self):
- """测试无效值异常的详细信息"""
- # Act
- exception = InvalidValueException(
- field_name="age",
- invalid_value=-5,
- reason="Age must be positive"
- )
-
- # Assert
- assert exception.details["field_name"] == "age"
- assert exception.details["invalid_value"] == "-5"
- assert exception.details["reason"] == "Age must be positive"
-
- def test_invalid_value_exception_with_additional_details(self):
- """测试带额外详细信息的无效值异常"""
- # Arrange
- additional_details = {"min_value": 0, "max_value": 150}
-
- # Act
- exception = InvalidValueException(
- field_name="age",
- invalid_value=-5,
- reason="Age out of range",
- details=additional_details
- )
-
- # Assert
- assert exception.details["min_value"] == 0
- assert exception.details["max_value"] == 150
- assert exception.details["field_name"] == "age"
-
- def test_invalid_value_exception_can_be_raised(self):
- """测试无效值异常可以被抛出和捕获"""
- # Act & Assert
- with pytest.raises(InvalidValueException) as exc_info:
- raise InvalidValueException(
- field_name="test",
- invalid_value="bad",
- reason="Test reason"
- )
-
- assert exc_info.value.field_name == "test"
- class TestBusinessRuleViolationException:
- """BusinessRuleViolationException 单元测试"""
-
- def test_create_business_rule_violation_exception(self):
- """测试创建业务规则违反异常"""
- # Act
- exception = BusinessRuleViolationException(
- rule_name="DocumentPublishRule",
- violation_reason="Cannot delete a published document"
- )
-
- # Assert
- assert exception.rule_name == "DocumentPublishRule"
- assert exception.violation_reason == "Cannot delete a published document"
- assert "DocumentPublishRule" in exception.message
- assert "Cannot delete a published document" in exception.message
-
- def test_business_rule_violation_exception_details(self):
- """测试业务规则违反异常的详细信息"""
- # Act
- exception = BusinessRuleViolationException(
- rule_name="QuotaLimitRule",
- violation_reason="User has exceeded document quota"
- )
-
- # Assert
- assert exception.details["rule_name"] == "QuotaLimitRule"
- assert exception.details["violation_reason"] == "User has exceeded document quota"
-
- def test_business_rule_violation_exception_with_additional_details(self):
- """测试带额外详细信息的业务规则违反异常"""
- # Arrange
- additional_details = {
- "document_id": "doc_123",
- "status": "published",
- "user_id": "user_456"
- }
-
- # Act
- exception = BusinessRuleViolationException(
- rule_name="DocumentDeletionRule",
- violation_reason="Published documents cannot be deleted",
- details=additional_details
- )
-
- # Assert
- assert exception.details["document_id"] == "doc_123"
- assert exception.details["status"] == "published"
- assert exception.details["user_id"] == "user_456"
-
- def test_business_rule_violation_exception_can_be_raised(self):
- """测试业务规则违反异常可以被抛出和捕获"""
- # Act & Assert
- with pytest.raises(BusinessRuleViolationException) as exc_info:
- raise BusinessRuleViolationException(
- rule_name="TestRule",
- violation_reason="Test violation"
- )
-
- assert exc_info.value.rule_name == "TestRule"
- class TestEntityNotFoundException:
- """EntityNotFoundException 单元测试"""
-
- def test_create_entity_not_found_exception(self):
- """测试创建实体未找到异常"""
- # Act
- exception = EntityNotFoundException(
- entity_type="Document",
- entity_id="doc_123"
- )
-
- # Assert
- assert exception.entity_type == "Document"
- assert exception.entity_id == "doc_123"
- assert "Document" in exception.message
- assert "doc_123" in exception.message
- assert "not found" in exception.message
-
- def test_entity_not_found_exception_details(self):
- """测试实体未找到异常的详细信息"""
- # Act
- exception = EntityNotFoundException(
- entity_type="KnowledgeBase",
- entity_id="kb_456"
- )
-
- # Assert
- assert exception.details["entity_type"] == "KnowledgeBase"
- assert exception.details["entity_id"] == "kb_456"
-
- def test_entity_not_found_exception_with_additional_details(self):
- """测试带额外详细信息的实体未找到异常"""
- # Arrange
- additional_details = {"search_criteria": {"name": "test"}}
-
- # Act
- exception = EntityNotFoundException(
- entity_type="User",
- entity_id="user_789",
- details=additional_details
- )
-
- # Assert
- assert exception.details["search_criteria"] == {"name": "test"}
-
- def test_entity_not_found_exception_can_be_raised(self):
- """测试实体未找到异常可以被抛出和捕获"""
- # Act & Assert
- with pytest.raises(EntityNotFoundException) as exc_info:
- raise EntityNotFoundException(
- entity_type="Test",
- entity_id="test_123"
- )
-
- assert exc_info.value.entity_type == "Test"
- class TestDomainValidationException:
- """DomainValidationException 单元测试"""
-
- def test_create_domain_validation_exception(self):
- """测试创建领域验证异常"""
- # Arrange
- validation_errors = [
- {"field": "name", "error": "Name is required"},
- {"field": "email", "error": "Email format is invalid"}
- ]
-
- # Act
- exception = DomainValidationException(validation_errors)
-
- # Assert
- assert exception.validation_errors == validation_errors
- assert "2 error(s)" in exception.message
-
- def test_domain_validation_exception_details(self):
- """测试领域验证异常的详细信息"""
- # Arrange
- validation_errors = [
- {"field": "age", "error": "Age must be positive"}
- ]
-
- # Act
- exception = DomainValidationException(validation_errors)
-
- # Assert
- assert exception.details["validation_errors"] == validation_errors
- assert exception.details["error_count"] == 1
-
- def test_domain_validation_exception_with_multiple_errors(self):
- """测试包含多个错误的领域验证异常"""
- # Arrange
- validation_errors = [
- {"field": "name", "error": "Name is required"},
- {"field": "email", "error": "Email is required"},
- {"field": "age", "error": "Age must be positive"}
- ]
-
- # Act
- exception = DomainValidationException(validation_errors)
-
- # Assert
- assert len(exception.validation_errors) == 3
- assert exception.details["error_count"] == 3
- assert "3 error(s)" in exception.message
-
- def test_domain_validation_exception_with_additional_details(self):
- """测试带额外详细信息的领域验证异常"""
- # Arrange
- validation_errors = [{"field": "test", "error": "Test error"}]
- additional_details = {"context": "user_registration"}
-
- # Act
- exception = DomainValidationException(
- validation_errors,
- details=additional_details
- )
-
- # Assert
- assert exception.details["context"] == "user_registration"
-
- def test_domain_validation_exception_can_be_raised(self):
- """测试领域验证异常可以被抛出和捕获"""
- # Arrange
- validation_errors = [{"field": "test", "error": "Test error"}]
-
- # Act & Assert
- with pytest.raises(DomainValidationException) as exc_info:
- raise DomainValidationException(validation_errors)
-
- assert len(exc_info.value.validation_errors) == 1
- class TestExceptionHierarchy:
- """测试异常层次结构"""
-
- def test_all_domain_exceptions_inherit_from_domain_exception(self):
- """测试所有领域异常都继承自 DomainException"""
- # Assert
- assert issubclass(InvalidValueException, DomainException)
- assert issubclass(BusinessRuleViolationException, DomainException)
- assert issubclass(EntityNotFoundException, DomainException)
- assert issubclass(DomainValidationException, DomainException)
-
- def test_can_catch_all_domain_exceptions_with_base_class(self):
- """测试可以使用基类捕获所有领域异常"""
- # Test InvalidValueException
- with pytest.raises(DomainException):
- raise InvalidValueException("field", "value", "reason")
-
- # Test BusinessRuleViolationException
- with pytest.raises(DomainException):
- raise BusinessRuleViolationException("rule", "reason")
-
- # Test EntityNotFoundException
- with pytest.raises(DomainException):
- raise EntityNotFoundException("Entity", "id")
-
- # Test DomainValidationException
- with pytest.raises(DomainException):
- raise DomainValidationException([{"field": "test", "error": "error"}])
|