断言可选具有特定值
2022-08-31 22:23:24
我有一个返回可选的Java方法。我想为它写一个易于阅读的单元测试,断言
返回的 Optional 有一个值(即,Optional 不为空),并且
返回值等于预期值。
假设我测试的方法是
Optional<String> testedMethod(){
return Optional.of("actual value");
}
我有一个返回可选的Java方法。我想为它写一个易于阅读的单元测试,断言
返回的 Optional 有一个值(即,Optional 不为空),并且
返回值等于预期值。
假设我测试的方法是
Optional<String> testedMethod(){
return Optional.of("actual value");
}
您还可以使用 AssertJ 进行流畅的断言
@Test
public void testThatOptionalIsNotEmpty() {
assertThat(testedMethod()).isNotEmpty();
}
@Test
public void testThatOptionalHasValue() {
assertThat(testedMethod()).hasValue("hello");
}
TL;DR 最好的整体方法是 Ole V. V.
assertEquals(Optional.of("expected"), opt);
其他替代方案将在下面讨论。
有几种不同的方法可以做到这一点,这取决于您对测试结果清晰度的品味与测试写作的简洁性。对于这个答案,我将坚持使用“库存”Java 8和JUnit 4,没有其他依赖项。
正如Ole V.V.的评论所建议的那样,一种方法是简单地写
assertEquals("expected", opt.get());
这主要有效,但如果可选为空,则将抛出 .这反过来又会导致 JUnit 发出错误信号,而不是失败,这可能不是您想要的。也不是很清楚发生了什么,除非你已经知道在这种情况下抛出NSEE。get()
NoSuchElementException
get()
另一种选择是
assertTrue(opt.isPresent() && "expected".equals(opt.get()));
这也主要有效,但如果存在不匹配,它不会报告实际值,这可能会使调试不方便。
另一种选择是
assertEquals("expected", opt.orElseThrow(AssertionFailedError::new));
这给出了正确的失败,并在存在不匹配时报告实际值,但对于抛出的原因并不是很明确。您可能需要盯着它看一会儿,直到您意识到AFE在可选为空时被抛出。AssertionFailedError
还有另一种选择是
assertEquals("expected", opt.orElseThrow(() -> new AssertionFailedError("empty")));
但这开始变得冗长。
你可以把它分成两个断言,
assertTrue(opt.isPresent());
assertEquals("expected", opt.get());
但是你以前因为冗长而反对这个建议。在我看来,这并不是非常冗长,但它确实有一些认知开销,因为有两个单独的断言,并且它依赖于第二个断言,只有在第一个成功时才被检查。这不是不正确的,但它有点微妙。
最后,如果您愿意创建一些自己的基础结构,则可以创建一个适当命名的子类,并按如下方式使用它:AssertionFailedError
assertEquals("expected", opt.orElseThrow(UnexpectedEmptyOptional::new));
最后,在另一条评论中,Ole V. V.建议
assertEquals(Optional.of("correct"), opt);
这工作得很好,实际上这可能是最好的。