服务单元可测试约定"助手类"在DDD模式

时间:2016-11-18 00:16:17

标签: java unit-testing design-patterns mockito domain-driven-design

我是Java的新手并加入了一个利用DDD模式的项目(据称)。我来自一个强大的python背景,并且相当肛门关于单元测试驱动设计。也就是说,迁移到Java的挑战之一是服务层的可测试性。

我们的类似REST的项目堆栈如下所示:

  • ServiceHandlers处理请求/响应等,并调用IService的特定实现(例如DocumentService
  • DocumentService - 使用makeOwner(session, user, doc)
  • 等方法处理审核,权限检查等

目前,DocumentService之类的东西通过guice注入了存储库依赖项。在像DocumentService.makeOwner这样的公共方法中,我们希望确保会话用户是管理员以及检查目标用户是否已经是所有者(利用注入的存储库)。这导致一些欺骗代码 - 一个用于解决用户并确保成员资格,权限等的用户。为了消除这个冗余代码,我想做一种超级简单的isOwner(user, doc)调用,我可以简洁地模拟out for各种测试场景(例如在用户无法解决时抛出异常等)。这是我的谷歌搜索让我失望的地方。

如果我将它与DocumentService放在同一个类中,我可以在同一个类中测试makeOwner时模拟它(由于Mockito限制),即使它有点像它应该去(选项1)。

如果我把它放在像DocumentHelpers这样的较低级别中,感觉有点滑稽,但我可以很容易地模仿出来。此外,DocumentHelpers也需要注入的存储库,这对guice很好。 (选项2)

我应该补充一点,在我们的婴儿代码库中有许多这种性质的点目前是不可测试的,因为方法在上层ServiceHandler类没有使用的同一* Service类中非静态地调用类似helper的方法。但是,在这个阶段,我无法判断这是不好的设计还是没问题。

所以我问更有经验的Java开发人员:

  1. 介绍"服务助手"看起来像是一个有效的解决方案?
  2. 这是DDD校长的反击吗?
  3. 如果没有,除了" Helpers"?
  4. 之外,是否有更多DDD友好的命名约定?

    要添加的3位:

    • 我的谷歌搜索主要是关于"助手"作为无状态操作的静态实用程序方法,如日期格式,这不适合我的问题。
    • 我不想使用PowerMock,因为它破坏了代码覆盖率并且使用起来非常难看。
    • 在python中,我可能会打电话给"服务助手"上面描述的层为internal_api,但在Java中似乎有不同的含义,特别是因为我需要将这些类公开来对它们进行单元测试。

    感谢任何指导。

1 个答案:

答案 0 :(得分:0)

启动操作的用户必须是管理员,看起来像应用程序级访问控制问题。 DDD对你应该如何做到这一点没有太多意见。出于可测试性和关注点分离的目的,有一种单独的非静态类可能比同一服务中的方法或静态助手更好。

检查未来的所有者是否已经是所有者(如果我理解正确的话)可能是另一种动物。它可能是您域中的不变量。如果是这样,首选方法是依靠Aggregate来强制执行该规则。但是,从您的描述中不清楚Document是否是聚合,以及它或其他聚合是否包含告知用户是否为所有者所需的数据。

或者,您可以在应用程序层级别验证规则,但这意味着如果状态更改由该应用程序层之外的其他内容触发,则您的域模型可能会不一致。