断言Optional具有一定的价值

时间:2016-08-15 12:04:06

标签: java unit-testing optional

我有一个返回Optional的Java方法。 我想写一个易于阅读的单元测试,断言

  1. 返回的Optional有一个值(即,Optional不为空)并且

  2. 返回的值等于预期值。

  3. 假设我的测试方法是

    Optional<String> testedMethod(){
      return Optional.of("actual value");
    }
    

5 个答案:

答案 0 :(得分:24)

您还可以使用AssertJ进行流畅断言

@Test
public void testThatOptionalIsNotEmpty() {
    assertThat(testedMethod()).isNotEmpty();
}

@Test
public void testThatOptionalHasValue() {
    assertThat(testedMethod()).hasValue("hello");
}

答案 1 :(得分:18)

TL; DR最佳整体方法由Ole V. V。建议:

assertEquals(Optional.of("expected"), opt);

下面讨论其他替代方案。

根据您对测试结果清晰度的要求与测试写作的简洁性,有几种不同的方法可以做到这一点。对于这个答案,我将坚持“库存”Java 8和JUnit 4,没有其他依赖。

正如comment by Ole V.V.中所建议的那样,只需编写

即可
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());

但你之前因为冗长而反对this suggestion。在我看来,这并不是非常非常冗长,但它确实有一些认知开销,因为有两个单独的断言,并且它依赖于第二个仅在第一个成功时被检查。这不是不正确的,但有点微妙。

最后,如果您愿意创建一些自己的基础架构,可以创建一个名为AssertionFailedError的适当命名的子类,并像这样使用它:

assertEquals("expected", opt.orElseThrow(UnexpectedEmptyOptional::new));

最后,在另一条评论中,Ole V. V.建议

assertEquals(Optional.of("correct"), opt);

这很有效,事实上这可能是最好的。

答案 2 :(得分:1)

我使用Hamcrest Optional

import static com.github.npathai.hamcrestopt.OptionalMatchers.hasValue;
import org.junit.Test;

public class MyUnitTests {

  @Test
  public void testThatOptionalHasValue(){
    String expectedValue = "actual value";
    assertThat(testedMethod(), hasValue(expectedValue));
  }
}

您可以将Hamcrest Optional添加到您的build.gradle

中,将其添加到您的依赖项中
dependencies {
  testCompile 'junit:junit:4.12'
  testCompile 'com.github.npathai:hamcrest-optional:1.0'
}

答案 3 :(得分:1)

以下方法使用的事实是您可以为可选项指定默认返回值。所以你的测试方法可能是这样的:

@test
public void testThatOptionalHasValue() {
    String expectedValue = "actual value";
    String actualValue = Optional.ofNullable(testedMethod()).orElse("not " + expectedValue);
    assertEquals("The values are not the same", expectedValue, actualValue);
}

这保证如果您的方法返回null,则结果不能与期望值相同。

答案 4 :(得分:0)

为什么不使用isPresent()get()