DDD рекомендует, чтобы объекты домена находились в допустимом состоянии в любое время. Совокупные корни отвечают за гарантирование инвариантов и Фабрики для сборки объектов со всеми необходимыми частями, чтобы они были инициализированы в правильном состоянии.Как сохранить простые тесты в единичных тестах и по-прежнему гарантировать наличие DDD-инвариантов?
Однако это, похоже, усложняет задачу создания простых изолированных изолированных тестов.
Предположим, у нас есть BookRepository, который содержит книги. Книга имеет:
- Автор
- категорию
- список Bookstores вы можете найти книгу в
Эти необходимые атрибуты: книга должна иметь автора, категории и, по крайней мере, книжный магазин, из которого вы можете купить книгу. Вероятно, существует BookFactory, поскольку это довольно сложный объект, и Factory будет инициализировать Книгу, по крайней мере, со всеми упомянутыми атрибутами. Возможно, мы также сделаем конструктор книги закрытым (и вложенным в Factory), чтобы никто не мог создать пустую книгу, кроме Factory.
Теперь мы хотим провести тестирование метода BookRepository, который возвращает все книги. Чтобы проверить, возвращает ли метод книги, мы должны настроить тестовый контекст (шаг Arrange в терминах AAA), где некоторые книги уже находятся в репозитории.
В C#:
[Test]
public void GetAllBooks_Returns_All_Books()
{
//Lengthy and messy Arrange section
BookRepository bookRepository = new BookRepository();
Author evans = new Author("Evans", "Eric");
BookCategory category = new BookCategory("Software Development");
Address address = new Address("55 Plumtree Road");
BookStore bookStore = BookStoreFactory.Create("The Plum Bookshop", address);
IList<BookStore> bookstores = new List<BookStore>() { bookStore };
Book domainDrivenDesign = BookFactory.Create("Domain Driven Design", evans, category, bookstores);
Book otherBook = BookFactory.Create("other book", evans, category, bookstores);
bookRepository.Add(domainDrivenDesign);
bookRepository.Add(otherBook);
IList<Book> returnedBooks = bookRepository.GetAllBooks();
Assert.AreEqual(2, returnedBooks.Count);
Assert.Contains(domainDrivenDesign, returnedBooks);
Assert.Contains(otherBook, returnedBooks);
}
Учитывая, что единственным инструментом в нашем распоряжении для создания объектов Book является завод, тест блок теперь использует и зависит от завода и inderectly по категориям, Автора и магазин, так как нам нужны эти объекты, чтобы создать книгу, а затем поместить ее в тестовый контекст.
Считаете ли вы, что это зависимость так же, как в тесте Service unit мы будем зависеть, скажем, от репозитория, который будет вызывать Служба?
Как бы вы решили проблему с повторным созданием целого кластера объектов, чтобы иметь возможность протестировать простую вещь? Как бы вы нарушили эту зависимость и избавились от всех этих атрибутов Книги, которые нам не нужны в нашем тесте? Используя макеты или заглушки?
Если вы макет вещи Repository содержит, какого рода фиктивных/окурков бы вы использовать в отличие от того, когда вы импровизировать что-то тестируемый объект переговоров с или потребляет?