"""领域层通用异常单元测试.""" import pytest from packages.domain.exceptions import ( DomainError, NotFoundError, QuotaExceededError, ValidationError, ) class TestDomainError: """DomainError 基类测试""" def test_is_exception(self): """DomainError 是 Exception 的子类""" assert issubclass(DomainError, Exception) def test_can_raise_and_catch(self): """可以抛出和捕获""" with pytest.raises(DomainError): raise DomainError("something went wrong") def test_message(self): """异常消息正确""" err = DomainError("test message") assert str(err) == "test message" class TestNotFoundError: """NotFoundError 测试""" def test_is_domain_error(self): """NotFoundError 继承自 DomainError""" assert issubclass(NotFoundError, DomainError) def test_can_raise_as_domain_error(self): """可以作为 DomainError 捕获""" with pytest.raises(DomainError): raise NotFoundError("resource not found") def test_default_message(self): """无参构造""" err = NotFoundError() assert isinstance(err, NotFoundError) def test_custom_message(self): """自定义消息""" err = NotFoundError("user 123 not found") assert str(err) == "user 123 not found" class TestValidationError: """ValidationError 测试""" def test_is_domain_error(self): """ValidationError 继承自 DomainError""" assert issubclass(ValidationError, DomainError) def test_can_raise_as_domain_error(self): """可以作为 DomainError 捕获""" with pytest.raises(DomainError): raise ValidationError("invalid input") def test_custom_message(self): """自定义消息""" err = ValidationError("duration must be positive") assert str(err) == "duration must be positive" class TestQuotaExceededError: """QuotaExceededError 测试""" def test_is_domain_error(self): """QuotaExceededError 继承自 DomainError""" assert issubclass(QuotaExceededError, DomainError) def test_can_raise_as_domain_error(self): """可以作为 DomainError 捕获""" with pytest.raises(DomainError): raise QuotaExceededError("storage", 1024.0, 2048.0) def test_stores_dimension_limit_used(self): """保存 dimension、limit、used 属性""" err = QuotaExceededError("storage_mb", 1024.0, 1500.0) assert err.dimension == "storage_mb" assert err.limit == 1024.0 assert err.used == 1500.0 def test_error_message_format(self): """异常消息格式正确""" err = QuotaExceededError("storage_mb", 1024.0, 1500.0) msg = str(err) assert "storage_mb" in msg assert "1500.0" in msg assert "1024.0" in msg assert "Quota exceeded" in msg def test_integer_values(self): """整数值也能正常工作""" err = QuotaExceededError("projects", 10, 15) assert err.dimension == "projects" assert err.limit == 10 assert err.used == 15 def test_zero_limit(self): """限制为 0 时也能正常工作""" err = QuotaExceededError("custom_templates", 0, 1) assert err.limit == 0 assert err.used == 1 class TestExceptionHierarchy: """异常继承关系测试""" def test_all_are_domain_errors(self): """所有异常都可以作为 DomainError 捕获""" errors = [ NotFoundError(), ValidationError("bad"), QuotaExceededError("x", 10.0, 20.0), ] for err in errors: assert isinstance(err, DomainError) def test_distinct_types(self): """不同异常类型可以区分""" assert not issubclass(NotFoundError, ValidationError) assert not issubclass(ValidationError, QuotaExceededError) assert not issubclass(NotFoundError, QuotaExceededError)