Files
xiaoxia-saas/tests/unit/test_domain_exceptions.py
T
CI Bot 008404f0af
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 37s
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Successful in 53s
CI/CD Pipeline / Frontend Lint (pull_request) Successful in 1m2s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m14s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m14s
Preview Deploy / Deploy Preview Environment (pull_request) Failing after 34s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 3m16s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 2m36s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 4m2s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m36s
AI Code Review / AI Code Review (pull_request) Successful in 4m26s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m33s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 11m8s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 52m0s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 18s
test: P3-1 第32波单元测试
- bgm_utils: 12个测试(BGM合并逻辑/优先级/兼容层)
- domain/exceptions: 18个测试(NotFound/Validation/QuotaExceeded/继承关系)
- asset_libraries use case: 10个测试(列表/创建/命令对象)

合计+40
2026-07-24 09:32:05 +08:00

132 lines
4.0 KiB
Python
Executable File

"""领域层通用异常单元测试."""
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)