将NullPointerException视为单元测试失败:这是一个好习惯吗?

时间:2012-10-25 12:46:56

标签: java unit-testing junit tdd testng

假设您有一个包含这些行的单元测试

assertNotNull(someVal);
assertNotEmpty(someVal);

这显然会检查someVal不为null并且填充了某些内容。

问题是,第一行是否必要,是否为测试添加了任何内容?我们不应该只有第二行,如果它是null,它将抛出一个空指针异常,它仍然表示一个失败的单元测试(但不是一个失败的断言)。

在这种简单的情况下,最佳做法是什么?

4 个答案:

答案 0 :(得分:4)

您不应该将NPE视为测试失败。您应该断言它不是null并提供错误消息,

assertNotNull(someVal, "Some descriptive message saying why value should not be null");

答案 1 :(得分:4)

这取决于。假设您正在测试函数myFunc。如果myFunc在非异常情况下返回null,我认为检查结果是否为非null和正确值是合理的,因为它可以使您的测试更清晰。

如果null是一个例外情况,那么检查它类似于在测试中捕获RuntimeException。只是弄乱你的测试并模糊你的意图。

答案 2 :(得分:3)

JUnit中的失败和错误之间存在差异。失败是预期的(用assertXXX()fail()明确测试),而错误则不是,通常是异常。请参阅What's the difference between failure and error in JUnit?

如果你打电话

assertNotNull(someVal);

然后你说这个值不应该为null,而且你专门测试它。如果你发生NullPointerException,那么解释错误的人将无法知道被测代码是否正确,或者你只是没有想到所有的情况。

这是一个意图问题。正如其他人所指出的那样,添加解释信息也是一个好主意。

答案 3 :(得分:2)

我不是assertNot()的忠实粉丝,更普遍地测试可能发生在SUT上的意外事情,更不用说在每次测试中测试它们以及普通的Assert。

IMO你应该只测试对象的名义状态。如果 正常,someVal在某些情况下为 ,则创建一个专用的测试方法,检查在该场景中它确实为空。为您的测试选择一个有意图的名称,例如someValShouldBeNullWhen...()。对空或任何其他值执行相同的操作。

通过查看测试异常消息,您可以看到意外情况发生在您的SUT上,而不是通过提前预测每个意外事件并使用assertNots为他们填写测试。