如何有效(不)测试服务层

时间:2010-09-23 08:22:54

标签: java unit-testing tdd jmock

在我们的一个服务类中,我有一堆方法只返回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大师:

您认为此测试带给项目的价值是什么?

我怎样才能更好地写出来?

3 个答案:

答案 0 :(得分:3)

经验法则测试可能破坏的所有内容。因此,如果您确信单线程在任何实际情况下都无法合理地破解,那么将其保留为未经测试可能没问题。但是,如果你已经对其中一些方法进行了工作单元测试,那么恕我直言就没有理由放弃它们 - 更多的单元测试从不会受到伤害,维护成本应该可以忽略不计。

实际上,该方法看起来微不足道。但是,还要考虑未来扩展/修改的可能性 - 在可预见的将来修改方法的任何真实机会都足以保证单元测试现在

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

恕我直言100%单元测试覆盖率几乎总是不切实际,在实际项目中是不必要的。通常有相当数量的例如异常处理代码难以测试琐碎,因此根据我的经验,它可能不值得努力。 首先关注最关键的部分,使用有限的资源获得最大的收益。如果像这样的方法是未经测试的最有趣的代码部分,你仍然有时间和精力来覆盖它们,你也可以绕过你的测试套件:-)然而,我担心大多数现实生活中的项目远离这种困境: - (

答案 1 :(得分:2)

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

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

但是,如果这里有一些额外的逻辑,例如选择DAO的任何条件或者传递的参数,那么我肯定会想要一些测试。

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

如果这是一个主导模式,那么我同意彼得·托拉克,这可能不值得努力。但是我会更多地关注集成测试来覆盖这个领域。

答案 2 :(得分:1)

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