【问题标题】:How to effectively (not) test service layer如何有效(不)测试服务层
【发布时间】:2010-09-23 20:05:29
【问题描述】:

在我们的一个服务类中,我有一堆方法,它们只返回 DAO 结果,没有像

这样的处理
public void acceptRequest(User from, User to) {
    rosterDAO.acceptRequest(from, to);
}

此方法的单元测试如下所示

private final RosterDAO rosterDAO = context.mock(RosterDAO.class);
...
public void testAcceptRequest() {
context.checking(new Expectations() {{
    oneOf (rosterDAO).acceptRequest(from, to);
    will (returnValue(1));
}
});

现在对我来说,这个测试看起来毫无意义,它唯一要做的就是测试该方法是否调用了另一个方法。 DAO 测试已经很好地覆盖了返回值。我很想放弃这些测试,因为我认为没有足够的内容来保证维护它们的努力。

所以对于坚持 100% 覆盖率的所有 TDD 专家来说:

您认为该测试为项目带来了什么价值?

我怎样才能写得更好?

【问题讨论】:

    标签: java unit-testing tdd jmock


    【解决方案1】:

    经验法则是测试所有可能破坏的东西。因此,如果您确信单线在任何实际情况下都无法合理地破坏,那么不对其进行测试可能就可以了。但是,如果您已经对其中一些方法进行了有效的单元测试,恕我直言,没有理由放弃它们 - 拥有更多的单元测试永远不会受到伤害,并且维护成本应该可以忽略不计。

    事实上,这个方法看起来很简单。但是,还要考虑未来扩展/修改的可能性 - 在可预见的将来修改方法的任何真正机会都足以证明现在进行单元测试。

    您可能希望通过集成测试覆盖更大的场景,以确保系统的不同部分作为一个整体在(接近)真实情况下按预期协同工作。

    恕我直言,100% 的单元测试覆盖率在实际项目中几乎总是不切实际和不必要的。通常有相当数量的例如难以测试的异常处理代码微不足道,因此根据我的经验,它可能不值得付出努力。 首先关注最关键的部分,利用有限的资源获得最大收益。如果像这样的方法是最有趣的未测试的代码部分,并且您仍然有时间和精力来涵盖它们,那么您也可以去完善您的测试套件 :-) 但是,恐怕大多数现实生活中的项目离这种困境还很远:-(

    【讨论】:

      【解决方案2】:

      要使这些测试变得有趣需要多少额外的复杂性?

      这里有三件事可能是错误的:从您可能拥有的所有其他 DAO 中选择 rosterDAO,以及您传递的两个参数:from 和 the to,例如可以在没有任何编译错误的情况下进行转置.碰巧你似乎不需要处理异常(顺便说一句,对吗?),所以我同意这是一个非常小的情况。

      但是,如果这里有一点额外的逻辑,例如选择 DAO 的任何条件或要通过哪些参数,那么我当然想要一些测试。

      那么从整体上看你的项目,这种方法是典型的吗?假设您有 20 种方法,其中 19 种确实具有条件,因此值得测试。在这种情况下,我只会让事情保持整洁并测试此方法 - 几乎没有任何工作要做。

      如果这是一种主导模式,那么我同意 Peter Torak 的观点,这可能不值得付出努力。但我会更加关注集成测试以涵盖这一领域。

      【讨论】:

        【解决方案3】:

        创建此特定方法的单元测试可能毫无意义,因为其中没有验证或业务逻辑(验证可能在 rosterDAO 级别)。但是,您应该使用真正的 rosterDAO 而不是模拟的方法来创建该方法的集成测试。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-04-15
          • 1970-01-01
          • 1970-01-01
          • 2012-01-25
          相关资源
          最近更新 更多