每个案例一个单元或每个断言一个单元

时间:2014-11-13 16:05:39

标签: java unit-testing

在单位测试中,我应该从支持成本的角度为每个案例写一个单元还是每个断言一个单元?我有以下代码

void methodUnderTest(Resource resource) {
    if(!resource.hasValue()) {
        Value value = valueService.getValue(resource);
        resource.setValue(value);
    }

    // resource.setLastUpdateTime(new Date()); // will be added in future
    db.persist(resource);
    email.send(resource);
}

评论行将在不久的将来添加,我认为更新单位会花费多少。

据我所知,有两种方法可以测试此代码。

  1. 写两个单位传递资源,其中包含值且没有值。在两个测试中,验证是否调用了db.persist和email.send。添加LastUpdateTime时,我必须更新两个测试以验证属性是否已设置。

  2. 编写单独的单元测试:一个检查db.persist是否被调用,另一个检查email.send,第三个和第四个是否为有和没有值的资源。添加LastUpdateTime时,我只需编写新单元。

  3. 我喜欢第二种方式因为我喜欢我不需要接触工作单位的想法。但这可能是很多代码重复,因为实际上所有4个测试都是相同的,只使用不同的断言。

    从“每单元测试的一个概念”的角度来看,第一种方法看起来更正确。但这些测试难以维持吗?添加新内容我将不得不修改所有现有的测试,听起来不太好。

    我应该遵循一些最佳做法吗?

2 个答案:

答案 0 :(得分:2)

我建议你将所有测试的常用内容放入测试的setUp()中,每个单元测试只有一个断言,就像你的第二种测试方法一样。

当您添加新的代码行时,您只需添加一个带有单个断言的测试用例。

不修改现有测试,不代码重复。

答案 1 :(得分:0)

对此没有一般答案。您需要平衡您的需求和约束:

  • 如果测试很小,快速执行并很少失败,则没有理由将其拆分为多个。
  • 如果你在一次测试中有很多断言,那么所有这些断言都可能为确定为什么测试失败提供了价值,但只有第一个将被执行,让您远离有价值的信息。尝试每次测试只有一个断言(combine the assertions into one big string, for example)。
  • 如果您在单个测试中测试多个功能,则可以使用"缺少有价值信息的变体。"如果每个测试都测试一个功能,那么成功和失败测试的组合可能会为您提供线索失败的线索。尝试针对每个测试使用一个功能。
  • 最后,当我看到数以千计的测试被执行时,它让我感觉良好。