"""领域层异常类单元测试.""" import pytest from packages.domain.exceptions import ( DomainError, NotFoundError, QuotaExceededError, ValidationError, ) class TestDomainError: """领域异常基类测试.""" def test_is_exception(self): """DomainError 继承自 Exception.""" err = DomainError("test") assert isinstance(err, Exception) def test_message(self): """可以设置错误消息.""" err = DomainError("something wrong") assert str(err) == "something wrong" def test_empty_message(self): """支持空消息.""" err = DomainError() assert str(err) == "" def test_can_be_raised(self): """可以被 raise 和 catch.""" with pytest.raises(DomainError) as exc_info: raise DomainError("oops") assert str(exc_info.value) == "oops" class TestNotFoundError: """资源不存在异常测试.""" def test_inherits_domain_error(self): """NotFoundError 继承自 DomainError.""" err = NotFoundError("user not found") assert isinstance(err, DomainError) assert isinstance(err, Exception) def test_message(self): """错误消息正确.""" err = NotFoundError("project 123 not found") assert str(err) == "project 123 not found" assert "123" in str(err) def test_can_catch_as_domain_error(self): """可以用 DomainError 捕获.""" with pytest.raises(DomainError): raise NotFoundError("not found") class TestValidationError: """校验失败异常测试.""" def test_inherits_domain_error(self): """ValidationError 继承自 DomainError.""" err = ValidationError("invalid input") assert isinstance(err, DomainError) def test_message(self): """错误消息正确.""" msg = "name must not be empty" err = ValidationError(msg) assert str(err) == msg def test_not_not_found(self): """ValidationError 不是 NotFoundError.""" err = ValidationError("bad") assert not isinstance(err, NotFoundError) class TestQuotaExceededError: """配额超限异常测试.""" def test_inherits_domain_error(self): """QuotaExceededError 继承自 DomainError.""" err = QuotaExceededError("storage", 100.0, 150.0) assert isinstance(err, DomainError) def test_dimension_attribute(self): """保存 dimension 属性.""" err = QuotaExceededError("storage", 100.0, 150.0) assert err.dimension == "storage" def test_limit_attribute(self): """保存 limit 属性.""" err = QuotaExceededError("storage", 100.0, 150.0) assert err.limit == 100.0 def test_used_attribute(self): """保存 used 属性.""" err = QuotaExceededError("storage", 100.0, 150.0) assert err.used == 150.0 def test_message_format(self): """错误消息格式正确.""" err = QuotaExceededError("credits", 50.0, 75.0) msg = str(err) assert "credits" in msg assert "50" in msg assert "75" in msg assert "Quota exceeded" in msg def test_zero_limit(self): """limit 为 0 的情况.""" err = QuotaExceededError("test", 0.0, 1.0) assert err.limit == 0.0 assert err.used == 1.0 assert "0" in str(err) def test_equal_limit_and_used(self): """used 刚好等于 limit(边界情况).""" err = QuotaExceededError("test", 100.0, 100.0) assert err.used == 100.0 assert err.limit == 100.0 def test_integer_values(self): """整数值也能正常工作.""" err = QuotaExceededError("count", 10, 20) assert err.dimension == "count" assert err.limit == 10 assert err.used == 20 def test_can_catch_as_domain_error(self): """可以用 DomainError 捕获.""" with pytest.raises(DomainError): raise QuotaExceededError("x", 1.0, 2.0) class TestExceptionHierarchy: """异常继承关系验证.""" def test_all_are_domain_errors(self): """所有领域异常都是 DomainError.""" errors = [ NotFoundError("test"), ValidationError("test"), QuotaExceededError("test", 1, 2), ] for err in errors: assert isinstance(err, DomainError) def test_all_are_exceptions(self): """所有领域异常都是 Exception.""" errors = [ DomainError("test"), NotFoundError("test"), ValidationError("test"), QuotaExceededError("test", 1, 2), ] for err in errors: assert isinstance(err, Exception) def test_not_found_is_not_validation(self): """不同异常类型不能互相混淆.""" assert not isinstance(NotFoundError("x"), ValidationError) assert not isinstance(ValidationError("x"), NotFoundError) assert not isinstance(QuotaExceededError("x", 1, 2), NotFoundError) assert not isinstance(QuotaExceededError("x", 1, 2), ValidationError)