Symfony 抽象DDD域中的功能测试

Symfony 抽象DDD域中的功能测试,symfony,domain-driven-design,functional-testing,Symfony,Domain Driven Design,Functional Testing,我正在使用Symfony2设计一个小型应用程序,将DDD域设想为一个供应商。这允许我通过不做任何假设来抽象我的领域。基本上,这个域是一组执行其内部工作的业务实体和服务。业务操作由简单的外观从外部(Symfony controllers)调用,该外观不暴露域中的任何内容 现在,我想测试我的域以验证其业务规则。考虑到这个域本身无法工作,因为它需要具体的存储库实现,我设置了测试来使用这些存储库的模拟。我的问题是:如何验证所有内部执行的域操作? 例如,假设我的域由两个实体组成:Article和Categ

我正在使用Symfony2设计一个小型应用程序,将DDD域设想为一个供应商。这允许我通过不做任何假设来抽象我的领域。基本上,这个域是一组执行其内部工作的业务实体和服务。业务操作由简单的外观从外部(Symfony controllers)调用,该外观不暴露域中的任何内容

现在,我想测试我的域以验证其业务规则。考虑到这个域本身无法工作,因为它需要具体的存储库实现,我设置了测试来使用这些存储库的模拟。我的问题是:如何验证所有内部执行的域操作?

例如,假设我的域由两个实体组成:
Article
Category
。我可以遍历一篇文章来获得它的类别,但我不能遍历一个类别来获得它的文章,因为它在我的域的上下文中没有意义。现在,我有一条业务规则规定,每当一个类别被禁用时,该类别上的所有文章都应该被禁用

此操作的入口点是
CategoryFacade
服务上的
disable($category)
方法。此操作将首先禁用该类别,然后获取该类别的所有文章并禁用它们

如果我从测试用例调用
disable()
操作,我可以验证我的类别是否被正确禁用,因为它是我正在执行测试的实际对象。但是那些文章呢?我的类别中没有
getArticles()
方法,而且由于我的域只使用mock作为存储库,因此手动获取文章并对其进行断言没有任何意义

编辑


下面提出的答案提醒了我一些关键的问题。事实上,在我的例子中,一个类别被视为AR,因为它的存在超出了文章的范围。但既然一篇文章也是AR,它就应该对其自身的一致性负全部责任。这意味着链接到某个类别的所有文章的停用不应该由类别服务发起,因为该服务不应该知道任何关于文章的信息。我的选择如下:每当类别被禁用时发送en event,并对我文章范围内的服务中的项目执行停用。

首先,最好不要将存储库与域逻辑一起测试,因为存储库只应在应用层中使用,那么你不应该测试应用程序服务。如果必须,那么只需创建一些测试存储库(基于内存)。 您应该只在域对象上测试业务规则。在示例中,如果要测试用户评级是否正常,请执行以下操作:

rated_user = UserFactory(parameters)
assertEqual(rated_user.rating, Rating(0))
rating_user = UserFactory(parameters)
rating_value = 3
rating_user.rateUser(rated_user, rating)
assertEqual(rated_user.rating, Rating(3))
测试您的案例是困难的,因为AR应该在不同的事务中更改(甚至可能不是在同一个请求中)。从您所说的来看,似乎Category应该是AR(聚合根),因为为了禁用Category,我们必须在不使用文章的情况下获取一个Category。 现在,当您禁用类别时,您应该发送文章应该获取的事件并禁用它本身。您可以通过调用EventListener回调来测试项目是否被禁用,这样会更好。同时测试两个AR实际上是一个集成测试,需要更多的设置

无论如何,要测试给定类别的所有文章是否都被禁用,您必须获取它们,可能需要使用类似“articlesRepository.getArticlesOfCategory(category)”的方法,并逐个检查是否被禁用。没有别的办法