ByteChannelReader { public void read(int length) throws IOException { if (_eof) { return; } _byteBuffer.compact(); while (_byteBuffer.position() < length) { int bytesRead = _readableByteChannel.read(_byteBuffer); if (bytesRead == -1) { _eof = true; break; } } _byteBuffer.flip(); } ByteChannelReader(ReadableByteChannel readableByteChannel);  ByteChannelReader(
			ReadableByteChannel readableByteChannel, int bufferLength); void ensureData(int length); byte get(); byte get(int offset); ByteBuffer getBuffer(); boolean hasRemaining(); boolean isSeekable(); void maybeRead(int length); void position(int position); void read(int length); int remaining(); void resizeBuffer(int minBufferLength); int skip(int length);  }
@Test public void testRead() throws IOException { ReadableByteChannel readableByteChannel = Mockito.mock( ReadableByteChannel.class); int length = 128; ByteChannelReader byteChannelReader = new ByteChannelReader( readableByteChannel, length); final ByteBuffer byteBuffer = byteChannelReader.getBuffer(); Answer answer = new Answer<Integer>() { @Override public Integer answer(InvocationOnMock invocationOnMock) throws Throwable { int bytesRead = byteBuffer.remaining(); if (_partialRead) { bytesRead--; } byteBuffer.put(new byte[bytesRead], 0, bytesRead); _partialRead = !_partialRead; return bytesRead; } private boolean _partialRead = true; }; Mockito.when( readableByteChannel.read(byteBuffer) ).then( answer ); int remainingData = 1025; while (remainingData > 0) { if (remainingData > length) { remainingData -= length; } else { length = remainingData; remainingData = 0; } byteChannelReader.ensureData(length); byteBuffer.get(new byte[length]); } }