Ответ
При разработке по DDD тестирование должно быть сфокусировано на доменном слое (Domain Layer), так как именно он содержит ключевую бизнес-логику, правила и инварианты, которые являются ядром и главной ценностью приложения.
Приоритеты тестирования (от высшего к низшему):
-
Агрегаты (Aggregates): Это главный объект тестирования. Тесты должны проверять:
- Соблюдение инвариантов: Агрегат не должен переходить в некорректное состояние. Например, сумма заказа не может быть отрицательной.
- Корректность выполнения команд: Все методы, изменяющие состояние агрегата, должны работать правильно.
- Генерацию доменных событий: После выполнения действия агрегат должен порождать правильные события (например,
OrderPlaced,ItemAdded).
-
Объекты-значения (Value Objects): Тесты проверяют их валидацию при создании и неизменяемость (immutability).
-
Доменные сервисы (Domain Services): Тестируется логика, которая координирует действия между несколькими агрегатами и не принадлежит ни одному из них.
Пример теста для агрегата Order:
func TestOrder_AddItem_EnforcesInvariants(t *testing.T) {
// Arrange: создаем заказ
order := NewOrder("order-123")
// Act: добавляем товар
err := order.AddItem("product-abc", 2, 150.0)
// Assert: проверяем результат
if err != nil {
t.Fatalf("Неожиданная ошибка при добавлении товара: %v", err)
}
// Проверяем, что инвариант (общая стоимость) соблюдается
if order.Total() != 300.0 {
t.Errorf("Ожидаемая стоимость 300.0, получено %f", order.Total())
}
// Проверяем, что было сгенерировано доменное событие
events := order.Events()
if len(events) != 1 || events[0].Name != "ItemAddedToOrder" {
t.Error("Ожидалось событие ItemAddedToOrder")
}
}
Тесты для других слоев (Application, Infrastructure) также важны, но они вторичны. Инфраструктурный слой (например, репозитории) часто покрывается интеграционными тестами, а не юнит-тестами.
Ответ 18+ 🔞
А, слушай, вот эта ваша DDD, блядь, — это ж надо же так мозги вынести! Но если разобраться, то главная фишка — это доменный слой, ёпта. Вся соль, вся бизнес-логика, все эти ваши правила, которые деньги приносят, — они там, в этом самом домене, как червяк в яблоке. Вот на нём и надо сосредоточиться, а не хуйнёй страдать!
Так, смотри, куда бить в первую очередь, по приоритету:
-
Агрегаты (Aggregates) — это святое, блядь! Вот их и долби тестами, как будто от этого жизнь зависит. Смотри, что проверять:
- Инварианты не нарушены? Чтобы заказ, например, в минус не ушёл, а то будет пиздец, а не бизнес.
- Команды работают? Вызвал метод — состояние изменилось так, как надо, а не как попало.
- События порождаются? Сделал что-то — агрегат должен пискнуть правильным событием, типа
OrderPlaced. Если молчит — значит, хуйня, а не агрегат.
-
Объекты-значения (Value Objects). Тут проще: создался — и навеки застыл, как памятник. Проверь, что при создании всё валидно, и что его после этого не сломаешь.
-
Доменные сервисы (Domain Services). Это когда логика не влезает в один агрегат, а болтается между ними, как манда с ушами. Вот её и тестируй, чтобы координация была чёткой.
Вот, смотри, как это примерно выглядит на коде, чтобы не быть просто болтуном:
func TestOrder_AddItem_EnforcesInvariants(t *testing.T) {
// Подготовка: создаём заказ, пока ещё пустой
order := NewOrder("order-123")
// Действие: пытаемся впихнуть товар
err := order.AddItem("product-abc", 2, 150.0)
// Проверка: а не обосрались ли мы?
if err != nil {
t.Fatalf("Неожиданная ошибка при добавлении товара: %v", err)
}
// Считаем бабки: инвариант должен быть в порядке
if order.Total() != 300.0 {
t.Errorf("Ожидаемая стоимость 300.0, получено %f", order.Total())
}
// А событие-то выстрелило? Должно!
events := order.Events()
if len(events) != 1 || events[0].Name != "ItemAddedToOrder" {
t.Error("Ожидалось событие ItemAddedToOrder, а тут какая-то хуйня!")
}
}
Остальные слои — прикладной, инфраструктурный — это, конечно, тоже надо тестировать, но это уже как бы второй эшелон. Инфраструктуру (типа репозиториев к базе) часто вообще интеграционными тестами проверяют, а не этими мелкими юнитами. Но домен — это священная корова, его надо вылизать до блеска, блядь!