单元测试 – 如何保持单元测试简单和隔离,并仍然保证DDD不变量?

前端之家收集整理的这篇文章主要介绍了单元测试 – 如何保持单元测试简单和隔离,并仍然保证DDD不变量?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
DDD建议域对象随时都应处于有效状态.聚合根负责保证不变量和工厂组装具有所有必需部分的对象,以便它们在有效状态下初始化.

然而,这似乎使创建简单,孤立的单元测试的任务复杂化.

假设我们有一个包含Books的BookRepository.一本书有:

>作者
>一个类别
>您可以在其中找到该书的书店列表

这些是必需的属性:一本书必须有一个作者,一个类别和至少一个书店,你可以从中购买这本书.
可能有一个BookFactory,因为它是一个非常复杂的对象,而Factory将至少用所有提到的属性初始化Book.也许我们还会将Book构造函数设置为私有(以及Factory嵌套),这样除了Factory之外没有人可以实例化一个空的Book.

现在我们想要单元测试BookRepository的一个方法,该方法返回所有的Books.为了测试该方法是否返回书籍,我们必须设置一个测试上下文(AAA术语中的Arrange步骤),其中一些Books已经存储在Repository中.

在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",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,并且仅依赖于Category,Author和Store,因为我们需要这些对象来构建Book然后将它放入测试环境.

您是否会认为这是一种依赖关系,就像在服务单元测试中我们将依赖于服务所调用的存储库一样?

您如何解决重新创建整个对象集群以便能够测试简单事物的问题?你如何打破这种依赖性并摆脱我们在测试中不需要的所有这些Book属性?通过使用模拟或存根?

如果你模拟了Repository包含的东西,你会使用什么样的模拟/存根,而不是当你模拟测试中的对象与之对话或消费时?

两件事情:

>在测试中使用模拟对象.您目前正在使用具体对象.
>关于复杂的设置,在某些时候你需要一些有效的书籍.将此逻辑提取到设置方法,以在每次测试之前运行.让该设置方法创建有效的书籍集合等等.

“How would you solve the problem of
having to re-create a whole cluster of
objects in order to be able to test a
simple thing ? How would you break
that dependency and get rid of all
these Book attributes we don’t need in
our test ? By using mocks or stubs ?”

模拟对象可以让你这样做.如果测试只需要一本有效作者的书,那么您的模拟对象将指定该作者,其他属性将被默认.由于您的测试只关心有效的作者,因此无需设置其他属性.

猜你在找的设计模式相关文章