有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java断言Optional具有一定的值

我有一个返回Optional的Java方法。 我想为它编写一个易于阅读的单元测试来证明

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

  2. 返回的值等于预期值

假设我的测试方法是

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

共 (5) 个答案

  1. # 1 楼答案

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

  2. # 2 楼答案

    下面的方法使用了一个事实,即您可以为可选项指定默认返回。所以你的测试方法可以是这样的:

    @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,那么结果就不能与期望值相同

  3. # 3 楼答案

    我用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));
      }
    }
    

    您可以通过将其包含在build.gradle中,将其添加到依赖项中:

    dependencies {
      testCompile 'junit:junit:4.12'
      testCompile 'com.github.npathai:hamcrest-optional:1.0'
    }
    
  4. # 4 楼答案

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

    @Test
    public void testThatOptionalIsNotEmpty() {
        assertThat(testedMethod()).isNotEmpty();
    }
    
    @Test
    public void testThatOptionalHasValue() {
        assertThat(testedMethod()).hasValue("hello");
    }
    
  5. # 5 楼答案

    TL;Ole V.V.博士提出了最佳的整体方法:

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

    下文将讨论其他替代方案

    有几种不同的方法可以做到这一点,这取决于你对测试结果清晰性和测试写作简洁性的喜好。对于这个答案,我将坚持使用“库存”Java 8和JUnit 4,没有其他依赖项

    正如comment by Ole V.V.中所建议的,一种方法就是简单地写

    assertEquals("expected", opt.get());
    

    这主要起作用,但如果可选项为空,那么get()将抛出NoSuchElementException。这反过来会导致JUnit发出错误信号,而不是失败信号,这可能不是您想要的。除非你已经知道在这种情况下get()抛出NSEE,否则也不太清楚发生了什么

    另一种选择是

    assertTrue(opt.isPresent() && "expected".equals(opt.get()));
    

    这也基本有效,但如果存在不匹配,它不会报告实际值,这可能会给调试带来不便

    另一种选择是

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

    这会给出正确的失败,并在出现不匹配时报告实际值,但对于抛出AssertionFailedError的原因并不是很明确。你可能得盯着它看一会儿,直到你意识到当可选项为空时会抛出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);
    

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