DDD では、ドメイン オブジェクトを常に有効な状態にすることをお勧めします。集約ルートは、オブジェクトが有効な状態で初期化されるように、必要なすべての部分でオブジェクトを組み立てるための不変条件とファクトリを保証する責任があります。
ただし、これにより、単純で分離された単体テストを作成するタスクが非常に複雑になるようです。
Books を含む BookRepository があるとします。本には次のものがあります。
- 著者
- カテゴリー
- その本を見つけることができる書店のリスト
これらは必須の属性です。書籍には、著者、カテゴリ、および少なくとも書籍を購入できる書店が必要です。これは非常に複雑なオブジェクトであるため、BookFactory が存在する可能性が高く、Factory は少なくとも前述のすべての属性で Book を初期化します。おそらく、Book コンストラクターを非公開 (および入れ子になった Factory) にして、Factory 以外の誰も空の Book をインスタンス化できないようにします。
次に、すべての本を返す BookRepository のメソッドを単体テストします。メソッドが本を返すかどうかをテストするには、一部の本がすでにリポジトリにあるテスト コンテキスト (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 オブジェクトを作成するために自由に使用できる唯一のツールが Factory であることを考えると、単体テストは Factory を使用し、これらのオブジェクトに間接的に依存しています。テストコンテキスト。
これは、サービスの単体テストで、たとえばサービスが呼び出すリポジトリに依存するのと同じように、依存関係であると考えますか?
単純なことをテストできるようにするために、オブジェクトのクラスター全体を再作成しなければならないという問題をどのように解決しますか? この依存関係を壊して、テストで不要な Book 属性をすべて取り除くにはどうすればよいでしょうか? モックまたはスタブを使用して?
リポジトリに含まれるものをモックアップする場合、テスト対象のオブジェクトが通信または消費するものをモックアップするときとは対照的に、どの種類のモック/スタブを使用しますか?