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

发布于 2024-09-24 06:46:32 字数 657 浏览 4 评论 0原文

在我们的一个服务类中,我有一堆方法,它们只返回 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 专家来说:

您认为这个测试给项目带来了什么价值?

我怎样才能写得更好?

In one of our service classes I have a bunch of methods which just return the DAO result with no processing like

public void acceptRequest(User from, User to) {
    rosterDAO.acceptRequest(from, to);
}

The unit test for this method looks like this

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

Now to me this test looks completely pointless, the only thing it does is test that the method calls another method. The return value is already well covered by the DAO tests.I'm tempted to drop these tests as I just don't think there's enough going on to warrant the effort to maintain them.

So for al you TDD gurus who insist on 100% coverage:

What value do you see this test bringing to the project?

How could I write it better?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

往事风中埋 2024-10-01 06:46:32

经验法则是测试所有可能损坏的东西。因此,如果您确信单线在任何实际情况下都不会合理破裂,那么最好不要对其进行测试。然而,如果您已经对其中一些方法进行了工作单元测试,恕我直言,没有理由放弃它们——进行更多的单元测试永远不会有什么坏处,而且维护成本应该可以忽略不计。

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

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

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

The rule of thumb is test everything which could possibly break. So if you are convinced that the one-liner can't reasonably break under any real circumstances, it may be fine to leave it untested. However, if you already have working unit tests for some of these methods, IMHO there is no reason to drop them - having more unit tests never hurts, and the maintenance costs should be negligible.

As it is, the method looks trivial enough. However, consider also the possibility of future extensions / modifications - any real chance of the method being modified in the foreseeable future is a strong enough case to warrant a unit test now.

You may want to cover the bigger scenario with an integration test though, to ensure that different parts of the system as a whole work together as expected under (close to) real circumstances.

IMHO 100% unit test coverage is almost always unrealistic and unnecessary in real-world projects. There is usually a fair amount of e.g. exception-handling code which is difficult to test and trivial, thus in my experience it may not simply worth the effort. Focus on the most critical parts first, using your limited resources to get the most benefit. If methods like this are the most interesting code parts left untested though, and you still have time and energy to cover them, you could just as well go and round your test suite out :-) However, I am afraid most real-life projects are far from this level of dilemmas :-(

沧桑㈠ 2024-10-01 06:46:32

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

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

然而,如果这里有一点额外的逻辑,例如选择 DAO 或要传递哪些参数的任何条件,那么我肯定需要一些测试。

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

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

How much extra complexity would it take to make these tests interesting?

Here there are three things that could be wrong: the choice of rosterDAO from all the other DAOs you may have, and the two parameters you are passing: the from and the to, which could for example be transposed without any compilation error. As it happens you seem to have no Exception handling to do (is that right by the way?), so I do agree that this is a pretty minimal case.

However, if there was a smidge of extra logic here, for example any conditionality in the selection of the DAO or which params to pass then I would certainly want some tests.

So looking at your project in the large, is this method typical? Suppose you had 20 methods, and 19 of them did have conditionality and so were worth testing. In that case, I would just leave things tidy and also test this method - it's hardly any work to do it.

If this is a dominant pattern then I agree with Peter Torak, it's probably not worth the effort. But I would pay more attention to integration testing to cover this area.

旧时模样 2024-10-01 06:46:32

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

It is probably pointless to create a unit test of this particular method as there is no validation or business logic in it (the validation is probably at the rosterDAO level). However, you should create integration tests of the method using a real rosterDAO rather than a mocked one.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文