| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- """
- 共享值对象单元测试
- 测试 EntityId 和 Timestamp 值对象的创建、验证和行为。
- """
- import pytest
- from datetime import datetime, timedelta
- from uuid import UUID, uuid4
- from src.domain.shared.value_objects import EntityId, Timestamp
- class TestEntityId:
- """EntityId 值对象单元测试"""
-
- def test_create_entity_id_with_valid_value(self):
- """测试使用有效值创建实体 ID"""
- # Arrange & Act
- entity_id = EntityId("doc_123")
-
- # Assert
- assert entity_id.value == "doc_123"
-
- def test_create_entity_id_with_empty_string_raises_error(self):
- """测试使用空字符串创建实体 ID 会抛出错误"""
- # Act & Assert
- with pytest.raises(ValueError, match="Entity ID cannot be empty"):
- EntityId("")
-
- def test_create_entity_id_with_whitespace_only_raises_error(self):
- """测试使用仅空格的字符串创建实体 ID 会抛出错误"""
- # Act & Assert
- with pytest.raises(ValueError, match="Entity ID cannot be whitespace only"):
- EntityId(" ")
-
- def test_create_entity_id_with_non_string_raises_error(self):
- """测试使用非字符串值创建实体 ID 会抛出错误"""
- # Act & Assert
- with pytest.raises(ValueError, match="Entity ID must be a string"):
- EntityId(123) # type: ignore
-
- def test_generate_creates_unique_id(self):
- """测试 generate 方法创建唯一 ID"""
- # Act
- id1 = EntityId.generate()
- id2 = EntityId.generate()
-
- # Assert
- assert id1.value != id2.value
- # 验证是有效的 UUID 格式
- UUID(id1.value)
- UUID(id2.value)
-
- def test_from_uuid_creates_entity_id(self):
- """测试从 UUID 创建实体 ID"""
- # Arrange
- uuid_value = uuid4()
-
- # Act
- entity_id = EntityId.from_uuid(uuid_value)
-
- # Assert
- assert entity_id.value == str(uuid_value)
-
- def test_entity_id_is_immutable(self):
- """测试实体 ID 是不可变的"""
- # Arrange
- entity_id = EntityId("doc_123")
-
- # Act & Assert
- with pytest.raises(AttributeError):
- entity_id.value = "doc_456" # type: ignore
-
- def test_entity_id_str_representation(self):
- """测试实体 ID 的字符串表示"""
- # Arrange
- entity_id = EntityId("doc_123")
-
- # Act & Assert
- assert str(entity_id) == "doc_123"
-
- def test_entity_id_repr_representation(self):
- """测试实体 ID 的详细表示"""
- # Arrange
- entity_id = EntityId("doc_123")
-
- # Act & Assert
- assert repr(entity_id) == "EntityId(value='doc_123')"
-
- def test_entity_id_equality(self):
- """测试实体 ID 的相等性比较"""
- # Arrange
- id1 = EntityId("doc_123")
- id2 = EntityId("doc_123")
- id3 = EntityId("doc_456")
-
- # Act & Assert
- assert id1 == id2
- assert id1 != id3
- class TestTimestamp:
- """Timestamp 值对象单元测试"""
-
- def test_create_timestamp_with_valid_datetime(self):
- """测试使用有效 datetime 创建时间戳"""
- # Arrange
- dt = datetime(2025, 1, 15, 10, 30, 0)
-
- # Act
- timestamp = Timestamp(dt)
-
- # Assert
- assert timestamp.value == dt
-
- def test_create_timestamp_with_non_datetime_raises_error(self):
- """测试使用非 datetime 对象创建时间戳会抛出错误"""
- # Act & Assert
- with pytest.raises(ValueError, match="Timestamp value must be a datetime object"):
- Timestamp("2025-01-15") # type: ignore
-
- def test_now_creates_current_timestamp(self):
- """测试 now 方法创建当前时间戳"""
- # Arrange
- before = datetime.now()
-
- # Act
- timestamp = Timestamp.now()
-
- # Arrange
- after = datetime.now()
-
- # Assert
- assert before <= timestamp.value <= after
-
- def test_from_iso_string_creates_timestamp(self):
- """测试从 ISO 字符串创建时间戳"""
- # Arrange
- iso_string = "2025-01-15T10:30:00"
-
- # Act
- timestamp = Timestamp.from_iso_string(iso_string)
-
- # Assert
- assert timestamp.value == datetime(2025, 1, 15, 10, 30, 0)
-
- def test_from_iso_string_with_invalid_format_raises_error(self):
- """测试从无效 ISO 字符串创建时间戳会抛出错误"""
- # Act & Assert
- with pytest.raises(ValueError, match="Invalid ISO timestamp string"):
- Timestamp.from_iso_string("invalid-date")
-
- def test_to_iso_string_converts_to_iso_format(self):
- """测试转换为 ISO 字符串"""
- # Arrange
- dt = datetime(2025, 1, 15, 10, 30, 0)
- timestamp = Timestamp(dt)
-
- # Act
- iso_string = timestamp.to_iso_string()
-
- # Assert
- assert iso_string == "2025-01-15T10:30:00"
-
- def test_is_before_returns_true_for_earlier_timestamp(self):
- """测试 is_before 对于更早的时间戳返回 True"""
- # Arrange
- ts1 = Timestamp(datetime(2025, 1, 15, 10, 0, 0))
- ts2 = Timestamp(datetime(2025, 1, 15, 11, 0, 0))
-
- # Act & Assert
- assert ts1.is_before(ts2)
- assert not ts2.is_before(ts1)
-
- def test_is_after_returns_true_for_later_timestamp(self):
- """测试 is_after 对于更晚的时间戳返回 True"""
- # Arrange
- ts1 = Timestamp(datetime(2025, 1, 15, 10, 0, 0))
- ts2 = Timestamp(datetime(2025, 1, 15, 11, 0, 0))
-
- # Act & Assert
- assert ts2.is_after(ts1)
- assert not ts1.is_after(ts2)
-
- def test_timestamp_is_immutable(self):
- """测试时间戳是不可变的"""
- # Arrange
- timestamp = Timestamp.now()
-
- # Act & Assert
- with pytest.raises(AttributeError):
- timestamp.value = datetime.now() # type: ignore
-
- def test_timestamp_str_representation(self):
- """测试时间戳的字符串表示"""
- # Arrange
- dt = datetime(2025, 1, 15, 10, 30, 0)
- timestamp = Timestamp(dt)
-
- # Act & Assert
- assert str(timestamp) == "2025-01-15T10:30:00"
-
- def test_timestamp_repr_representation(self):
- """测试时间戳的详细表示"""
- # Arrange
- dt = datetime(2025, 1, 15, 10, 30, 0)
- timestamp = Timestamp(dt)
-
- # Act & Assert
- assert "Timestamp(value=" in repr(timestamp)
-
- def test_timestamp_equality(self):
- """测试时间戳的相等性比较"""
- # Arrange
- dt = datetime(2025, 1, 15, 10, 30, 0)
- ts1 = Timestamp(dt)
- ts2 = Timestamp(dt)
- ts3 = Timestamp(dt + timedelta(seconds=1))
-
- # Act & Assert
- assert ts1 == ts2
- assert ts1 != ts3
-
- def test_timestamp_comparison_operators(self):
- """测试时间戳的比较运算符"""
- # Arrange
- ts1 = Timestamp(datetime(2025, 1, 15, 10, 0, 0))
- ts2 = Timestamp(datetime(2025, 1, 15, 11, 0, 0))
- ts3 = Timestamp(datetime(2025, 1, 15, 11, 0, 0))
-
- # Act & Assert
- assert ts1 < ts2
- assert ts1 <= ts2
- assert ts2 > ts1
- assert ts2 >= ts1
- assert ts2 <= ts3
- assert ts2 >= ts3
-
- def test_timestamp_equality_with_non_timestamp_returns_false(self):
- """测试时间戳与非时间戳对象比较返回 False"""
- # Arrange
- timestamp = Timestamp.now()
-
- # Act & Assert
- assert timestamp != "not a timestamp"
- assert timestamp != 123
- assert timestamp != None
|