CloseableStreamIterator implements AutoCloseable, Iterator<T> { @Override public void close() { if (this.stream != null) { this.stream.close(); } } CloseableStreamIterator(Supplier<Stream<T>> streamSupplier); @Override boolean hasNext(); @Override T next(); @Override void close(); Stream<T> getRemainingStream();  }
@Test @DisplayName("closes stream when closing remaining stream") public void testClosesOriginalStream() { List<String> firstElements = new ArrayList<>(); try (Stream<String> stream = splitStream(firstElements, 2)) { assertThat(firstElements).containsExactly("A", "B"); assertThat(stream).containsExactly("C", "D", "E"); verify(resource, never()).close(); } verify(resource).close(); }
@Test @DisplayName("closes original Stream after Exception in constructor") public void testClosesOriginalStreamAfterExceptionInConstructor() { try { CloseableStreamIterator<String> iter = newInstance(actualStream -> { Stream<String> riggedStream = mockDelegateTo(Stream.class, actualStream); when(riggedStream.iterator()).thenThrow(new UnsupportedOperationException("Test")); return riggedStream; }); fail("Expected UnsupportedOperationException to be thrown"); } catch (UnsupportedOperationException exc) { } verify(resource).close(); }