2016-04-06 6 views
0

次のコードは、ストリームのサイズに関するより自然なアサーションを可能にするように設計されています。マッチャの作成<Stream>(jUnit)

Matcher<Stream> hasCount(int count) { 
    return new TypeSafeDiagnosingMatcher<Stream>() { 
     protected boolean matchesSafely(Stream stream, Description desc) { 
      long streamCount = stream.count(); 
      if (streamCount == count) { 
       return true; 
      } else { 
       desc.appendText("count ").appendValue(streamCount); 
       return false; 
      } 
     } 

     public void describeTo(Description desc) { 
      desc.appendText("count ").appendValue(count); 
     } 
    }; 
} 

これは、のようなアサーションができます:それはエラー が「ストリームがすでに時に操作または閉鎖されている」返すアサーションが通過するときにそれが正常に動作しますが、それが失敗したとき

assertThat(getWidgetStream(), hasCount(52)); 

(例えばassertThat(Stream.empty(), hasCount(1));を)予想される説明「expected:count < 1」ではなく、「< 0>」となります。

TypeSafeDiagnosingMatcherのソースを確認したところ、matchesdescribeMismatchの両方からmatchesSafelyが呼び出されました。だからHamcrestはmatchesSafelyが私のものではない冪等であると仮定しています。

この問題を回避する方法はありますか?

答えて

0

私が発見した1つの解決策は、呼び出し間に結果を格納することです。

return new TypeSafeDiagnosingMatcher<Stream>() { 
    private Optional<Long> streamCount = Optional.empty(); 

    protected boolean matchesSafely(Stream stream, Description desc) { 
     if (!streamCount.isPresent()) 
      streamCount = Optional.of(stream.count()); 
     if (streamCount.get() == count) { 
      return true; 
     } else { 
      desc.appendText("has count ").appendValue(streamCount.get().intValue()); 
      return false; 
     } 
    } 
}; 

これは機能しますが、特に優雅ではありません。

+0

'mtachedSafely'は' describedTo'の後に 'but:... 'の部分のデシジョンを生成するために2度目に呼び出されます。それは行く方法だと思われる。 – SubOptimal

+0

@SubOptimalはいこれは最も簡単な解決策だと思われますが、hamcrestでは 'matchesSafely'を2回呼び出すことができると考えているようです。 – sprinter

+1

しかし[IsCollectionContainingTest.java](https://github.com/hamcrest/JavaHamcrest/blob/master/hamcrest-core/src/test/java/org/hamcrest/core/IsCollectionContainingTest.java#L89)を見てくださいこれは意図された方法です。 – SubOptimal

関連する問題