单元测试 – 如何保持单元测试简单和隔离,并仍然保证DDD不变量?
DDD建议域对象随时都应处于有效状态.聚合根负责保证不变量和工厂组装具有所有必需部分的对象,以便它们在有效状态下初始化.
然而,这似乎使创建简单,孤立的单元测试的任务复杂化. 假设我们有一个包含Books的BookRepository.一本书有: >作者 这些是必需的属性:一本书必须有一个作者,一个类别和至少一个书店,你可以从中购买这本书. 现在我们想要单元测试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包含的东西,你会使用什么样的模拟/存根,而不是当你模拟测试中的对象与之对话或消费时?
两件事情:
>在测试中使用模拟对象.您目前正在使用具体对象.
模拟对象可以让你这样做.如果测试只需要一本有效作者的书,那么您的模拟对象将指定该作者,其他属性将被默认.由于您的测试只关心有效的作者,因此无需设置其他属性. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |