5

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

assertNotNull(someVal);
assertNotEmpty(someVal);

这显然检查 someVal 不是 null 并且填充了一些东西。

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

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

4

4 回答 4

5

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

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

于 2012-10-25T12:50:30.530 回答
4

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

如果 null 是一个例外情况,那么检查它类似于在测试中捕获 RuntimeException。只会使您的测试混乱并掩盖您的意图。

于 2012-10-25T12:53:02.043 回答
3

JUnit 中的失败和错误是有区别的。失败是预期的(使用assertXXX()or显式测试fail()),错误是非预期的,通常是异常。请参阅JUnit 中的失败和错误有什么区别?.

如果你打电话

assertNotNull(someVal);

那么你是说这个值不应该为空,而你正在专门测试它。如果您让 NullPointerException 发生,那么解释错误的人将不知道被测代码是否正确,或者您只是没有考虑所有情况。

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

于 2012-10-25T12:54:21.983 回答
2

我不是assertNot()'s 的忠实拥护者,更普遍地测试 SUT 可能发生的意外事情,更不用说在每个测试中除了正常的 Assert 之外测试它们。

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

通过查看测试异常消息,您可以看到 SUT 发生了意外的事情,而不是通过尝试提前预测这些意外的事情并为它们使用 assertNots 来填充您的测试。

于 2012-10-25T13:18:34.577 回答