方法前提条件是否应该进行单元测试?

Should method preconditions be unit tested?

我使用 Guava 的 Preconditions 来验证我方法的输入,例如:

class TestedClass {
  public double sqrt(double value) {
    Preconditions.checkArgument(value >= 0.0, "negative value: %s", value);
  }
}

我想知道先决条件是否应该进行单元测试?我是否应该进行测试:

@Rule
public ExpectedException exception = ExpectedException.none();

@Test
public void shouldFailWhenValueIsNegative() {
   exception.thown(IllegalArgumentException.class);
   exception.expectMessage("negative value: -1");

   new TestedClass().sqrt(-1);
} 

我认为您主要会在这里获得意见,但我想说这通常不值得花时间。如果您有 8 个参数都经过前提条件检查怎么办?如果需要 7/8,是否要测试所有参数组合?我宁愿文档具体使用 Optional<> 类型或使用 @Nullable@Nonnull 类型注释来帮助自记录代码。

我喜欢 Guava 的处理方式,它 annotates the whole package@ParametersAreNonnullByDefault

@ParametersAreNonnullByDefault
package com.google.common.base;

为了提出相反的论点(和 'It depends' 持观望态度),如何检查先决条件是一个实现细节,事实是您想要的行为是异常如果违反先决条件则抛出。鉴于此,我认为您应该在测试中检查这些条件,因为您的测试应该验证行为是否符合您的预期。

话虽如此,我认为这取决于检查的先决条件是什么,以及它们是如何应用的。如果您正在对整个包应用注释,以便不允许传递任何空值,那么对我来说,然后通过对每种方法进行测试来检查它就没有意义。

但是在您的示例中,您正在检查 sqrt 函数中的某些特定内容,恕我直言,您正在检查一项特定技术这一事实是无关紧要的,您应该对其进行测试以验证该方法的行为。

我的意见是,是的,您通常应该进行测试,以验证您的方法的行为是否符合其合同规定的行为(包括先决条件)。如果您说您的方法在给定参数负值时抛出特定异常,请进行测试以确保这是真的。

对于像 NullPointerException 这样非常常见的东西,guava-testlibNullPointerTester,我们用它来测试 NPE 是针对没有用 [ 注释的参数抛出的=14=].