2016-08-15 11 views
11

Optionalを返すJavaメソッドがあります。私はオプションに特定の値があることをアサートする

  1. 返されたオプションが値を持っている(つまり、オプションが空でない)と

  2. ということを主張することのために読みやすいユニットテストを書きたいと思い 戻り値は期待値に等しい。

    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オプションを追加することができます:

私はそのためにHamcrest Optionalを使用するのは、私のテスト方法は

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

私は単に 'assertEquals(" actual value "、testedMethod()。get());'オプションを空にすると例外が発生し、ユニットテストが失敗するのに十分です。本当に何も必要ありません。 –

答えて

12

また、流暢なアサーション

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

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

あるとしましょう

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

isPresent()get()を使用しないでください。

+0

これは2つのアサーションであり、非常に冗長なユニットテストになります。私は何かを探していた。 –

1

以下のアプローチはオプションのためのデフォルトの戻り値を指定することができるという事実を利用するためAssertJを使用することができます。これはあなたのメソッドがnullを返した場合、その結果は期待値と同じにすることができないというguarentees

@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); 
} 

:だからあなたの試験方法は次のようなものである可能性があります。

12

テストの簡潔性とテストの簡潔さのために、好みに応じていくつかの方法があります。この回答のために、私は "在庫" Java 8とJUnit 4を追加の依存関係なしで固執します。

一つの方法は、comment by Ole V.V.で提案されているように、これは主に動作しますが、オプションが空の場合は、その後、get()NoSuchElementExceptionをスローします

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

を書くことだけです。これは、JUnitに障害の代わりにエラーを通知させます。これは、必要ではない可能性があります。この場合、get()がNSEEをスローすることを既に知っていない限り、何が起こっているのかはあまり明確ではありません。

代替は

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

これもほとんどが作品ですが、デバッグが不便になるかもしれない不一致、ありますかどうかは、実際の値を報告しません。

別の方法としては、これは正しい障害を与え、不一致があります時に実際の値を報告し

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

ですが、それはAssertionFailedErrorがスローされた理由について非常に明確なではありません。 Optionalが空のときにAFEがスローされることがわかるまで、しばらくそれを見ておく必要があります。

さらに別の代替は

assertEquals("correct", opt.orElseThrow(() -> new AssertionFailedError("empty"))); 

であるが、これは冗長取得し始めています。次の2つのアサーションにこれを分割することができ

は、

assertTrue(opt.isPresent()); 
assertEquals("correct", opt.get()); 

いますが、以前ため、冗長性のthis suggestionに反対していました。私の意見では、これは本当にひどく冗長ではありませんが、2つの別々のアサーションがあるので、いくつかのコグニティブオーバーヘッドがあります。これは間違っているわけではありませんが、少し微妙です。あなたがあなた自身のインフラストラクチャのビットを作成するために喜んでいる場合

最後に、あなたはAssertionFailedErrorの適切な名前のサブクラスを作成し、このようにそれを使用することができます。コメントは、オレには

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

UPDATE VV提案

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

これは非常にうまくいきますが、実際にはこれが最高のものかもしれません。

+0

値が存在しないという別の従来の表現として 'null'を受け入れるなら、' assertEquals( "correct"、opt.orElse(null)); 'もあります。それは私の個人的な好みではありませんが、それはあなたのものであるべきです。 –

+10

もう一度考えると、 'assertEquals(options al.of(" correct ")、opt);もあります。それは簡潔で、それを書いているのを考えるのに私はしばらくかかりましたが、読むのは大丈夫ですか? 'opt'が間違った値を保持している場合と空である場合の両方で、失敗について素敵で明確なメッセージを与えることも期待します。 –

+0

@ OleV.V。良い提案! –

関連する問題