为什么JUnit测试方法需要是void?

5

我在很多地方读到测试方法应该/必须是void,但没有人说这样做的原因。

我在MethodValidator中发现了以下检查,没有注释/ javadocs。

    if (each.getReturnType() != Void.TYPE) {
        errors.add(new Exception("Method " + each.getName()
                + " should be void"));
    }

那么为什么它应该是void

6
为什么单元测试会不是void类型?从单元测试方法返回值没有意义,因此,如果一个单元测试方法返回一个值,那么它很可能不是正确的单元测试或者不是旨在进行单元测试的方法。 - Mark Rotteveel
2
因为没有人会查看它们的返回值? - user207421
2个回答

5
问一个相反的问题:为什么JUnit测试方法不需要是void类型的?没有理由,因为测试方法不设计返回结果供客户类利用。单元测试的目标是验证某些断言。测试运行程序调用测试方法,这个程序解释测试执行期间产生的任何断言失败或异常抛出来生成测试结果。
我们可以想一下为什么测试不返回断言结果。但这是个不好的主意,因为编写单元测试将会非常麻烦。
@Test
public AssertionResult foo(){
   Bar actualBar = foo.doThat(...);
   if (actualBar == null){
       return AssertionResult.fail("actualBar == null");
   }
}

请编写易于阅读且简明易懂的内容:

@Test
public void foo(){
   Bar actualBar = foo.doThat(...);
   Assert.assertNotNull(actualBar);
}

我们也可以想知道为什么测试方法不能被其他测试方法调用,例如:

@Test
public int foo(){
   Bar actualBar = foo.doThat(...);
   //...
   return intValue;
}

@Test
public void fooWithComputedInt(){
   Bar actualBar = foo.doThat(foo());
   //...
}

但这也不是一个好主意,因为这会使测试执行与单元测试执行耦合在一起,而单元测试必须与其他测试隔离开来。同时,这也将导致测试被多次执行,而单元测试必须尽可能快地执行。

因此,除了void之外,让测试方法返回其他内容真的没有任何价值。


我相信你知道你在说什么,但我一点也不知道。 - martinseal1987

1
这纯粹是一种设计选择。JUnit不了解你的代码,所以如果你的方法返回值,它就无法执行任何操作。
因此,它应该丢弃返回值或要求您使用“void”方法。作者选择了后者选项 - 可以认为这更好,因为它不会让读者感到困惑。
请注意,非@Test方法可以自由地做任何他们想做的事情 - 他们没有这个限制。

JUnit无法执行任何操作的原因是,如果我的方法返回了某个值,它会阻塞JUnit的执行。 - Artem Malchenko
@ArtemMalchenko 它并不会以任何方式阻止它。JUnit 调用您的 @Test 方法 - 只是没有约定如果您的方法返回一个值应该做什么。任何成功/失败的检查都使用断言(即可抛出的异常)完成 - 您可以说这是 "JUnit 关心的唯一结果"(尽管它实际上不是一个 "返回")。 - jurez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接