我有一个返回 Optional 的 Java 方法。我想为它编写一个易于阅读的单元测试,断言
返回的 Optional 有一个值(即 Optional 不为空)并且
返回值等于预期值。
假设我的测试方法是
Optional<String> testedMethod(){
return Optional.of("actual value");
}
原文由 Matthias Braun 发布,翻译遵循 CC BY-SA 4.0 许可协议
我有一个返回 Optional 的 Java 方法。我想为它编写一个易于阅读的单元测试,断言
返回的 Optional 有一个值(即 Optional 不为空)并且
返回值等于预期值。
假设我的测试方法是
Optional<String> testedMethod(){
return Optional.of("actual value");
}
原文由 Matthias Braun 发布,翻译遵循 CC BY-SA 4.0 许可协议
TL; DR Ole VV 建议的最佳整体方法:
assertEquals(Optional.of("expected"), opt);
下面讨论其他替代方案。
有几种不同的方法可以做到这一点,具体取决于您对测试结果的清晰度与测试写作的简洁性的偏好。对于这个答案,我将坚持使用没有额外依赖项的“常用”Java 8 和 JUnit 4。
正如 Ole VV 的评论 中所建议的,一种方法是简单地编写
assertEquals("expected", opt.get());
这主要有效,但如果 Optional 为空,则 get()
将抛出 NoSuchElementException
。这反过来会导致 JUnit 发出错误信号而不是失败信号,这可能不是您想要的。除非您已经知道 get()
在这种情况下抛出 NSEE,否则还不是很清楚发生了什么。
另一种选择是
assertTrue(opt.isPresent() && "expected".equals(opt.get()));
这也大多有效,但如果存在不匹配,它不会报告实际值,这可能会使调试变得不便。
另一种选择是
assertEquals("expected", opt.orElseThrow(AssertionFailedError::new));
这给出了正确的失败并在存在不匹配时报告实际值,但是对于抛出 AssertionFailedError
的原因并不是很明确。您可能不得不盯着它看一会儿,直到您意识到当 Optional 为空时会抛出 AFE。
还有另一种选择是
assertEquals("expected", opt.orElseThrow(() -> new AssertionFailedError("empty")));
但这开始变得冗长。
你可以把它分成两个断言,
assertTrue(opt.isPresent());
assertEquals("expected", opt.get());
但是你之前因为冗长而反对 这个建议。在我看来,这并不是非常冗长,但它确实有一些认知开销,因为有两个单独的断言,并且它依赖于第二个只有在第一个成功时才被检查。这并没有错,但有点微妙。
最后,如果你愿意创建一些你自己的基础设施,你可以创建一个适当命名的子类 AssertionFailedError
并像这样使用它:
assertEquals("expected", opt.orElseThrow(UnexpectedEmptyOptional::new));
最后,在另一条评论中,Ole VV 建议
assertEquals(Optional.of("correct"), opt);
这工作得很好,事实上这可能是最好的。
原文由 Stuart Marks 发布,翻译遵循 CC BY-SA 3.0 许可协议
15 回答8.4k 阅读
8 回答6.2k 阅读
1 回答4k 阅读✓ 已解决
3 回答6k 阅读
3 回答2.2k 阅读✓ 已解决
2 回答3.1k 阅读
2 回答3.8k 阅读
您还可以使用 AssertJ 进行流畅的断言