2016-04-06 3 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));) возвращает ошибку «поток уже работает на или закрыто» а не ожидаемое описание "ожидается: count < 1> had: count < 0>".

Когда я проверил источник для TypeSafeDiagnosingMatcher, я обнаружил, что matchesSafely вызывается из matches и describeMismatch. Так что 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' для создания decription для '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

Смежные вопросы