2016-04-06 19 views
0

下面的代碼旨在允許有關流大小的更自然的斷言。爲jUnit創建匹配程序<Stream>

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));)則返回錯誤 「流已在運行或關閉」而不是預期的描述「預計:計數< 1>具有:計數< 0>」。

當我檢查TypeSafeDiagnosingMatcher的源時,我發現從matchesdescribeMismatch都調用matchesSafely。所以Hamcrest假設matchesSafely是冪等的,而我的不是。

有沒有辦法解決這個問題?

回答

0

我發現的一個解決方案是在調用之間存儲結果。

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'在'describeTo'之後第二次被調用以產生'but:...'部分的描述。這似乎是要走的路。 – SubOptimal

+0

@SubOptimal是的,我懷疑這是最簡單的解決方案,但它似乎有點像hamcrest中的一個缺陷,認爲'matchesSafely'可以被調用兩次。 – sprinter

+1

但看着[IsCollectionContainingTest.java](https://github.com/hamcrest/JavaHamcrest/blob/master/hamcrest-core/src/test/java/org/hamcrest/core/IsCollectionContainingTest.java#L89)它似乎這是預期的方式。 – SubOptimal