web-dev-qa-db-ja.com

Optionalに特定の値があることをアサートする

Optional を返すJavaメソッドがあります。読みやすいユニットを書きたいですそれを主張するそれのためのテスト

  1. 返されるOptionalには値があり(つまり、Optionalは空ではありません)

  2. 返される値は期待値と同じです。

私のテスト済みのメソッドが

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

また、流fluentなアサーションには AssertJ を使用できます。

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

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

TL; DR Ole V. V.により、全体的な最良のアプローチが提案されました。

_assertEquals(Optional.of("expected"), opt);
_

他の選択肢については以下で説明します。

これを行うにはいくつかの異なる方法がありますが、テスト結果を明確にするか、テスト記述を簡潔にするかによって、好みが異なります。この回答については、「stock」Java 8およびJUnit 4に依存し、追加の依存関係はありません。

Ole V.V.によるコメント で示唆されている1つの方法は、単に書くことです

_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")));
_

しかし、これは冗長になり始めています。

これを2つのアサーションに分割できます。

_assertTrue(opt.isPresent());
assertEquals("expected", opt.get());
_

しかし、以前は冗長性のために この提案 に反対していました。私の意見ではこれはそれほど冗長ではありませんが、2つの独立したアサーションがあるため、認識上のオーバーヘッドがあります。最初のものが成功した場合にのみ、2番目のものがチェックされます。これは間違っていませんが、少し微妙です。

最後に、独自のインフラストラクチャを少しでも作成する場合は、AssertionFailedErrorの適切な名前のサブクラスを作成し、次のように使用できます。

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

最後に、別のコメントで、オレV. V.は提案した。

_assertEquals(Optional.of("correct"), opt);
_

これは非常にうまく機能し、実際、これが何よりも優れている可能性があります。

19
Stuart Marks

私は Hamcrestオプション を使用します:

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に含めることで、依存関係にHamcrest Optionalを追加できます。

dependencies {
  testCompile 'junit:junit:4.12'
  testCompile 'com.github.npathai:hamcrest-optional:1.0'
}
2
Matthias Braun

以下のアプローチでは、オプションのデフォルトのリターンを指定できるという事実を使用しています。したがって、テストメソッドは次のようになります。

@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を返す場合、結果が期待値と同じにならないことを保証します。

1
Ben Green

isPresent()get()を使用しないのはなぜですか?

0
mzq