### Question:
DefaultHttp2ConnectionDecoder implements Http2ConnectionDecoder { private int unconsumedBytes(final Http2Stream stream) { return flowController().unconsumedBytes(stream); } DefaultHttp2ConnectionDecoder(
      final Http2Connection connection,
      final Http2ConnectionEncoder encoder,
      final Http2FrameReader frameReader);  DefaultHttp2ConnectionDecoder(
      final Http2Connection connection,
      final Http2ConnectionEncoder encoder,
      final Http2FrameReader frameReader,
      final Http2PromisedRequestVerifier requestVerifier);  DefaultHttp2ConnectionDecoder(
      final Http2Connection connection,
      final Http2ConnectionEncoder encoder,
      final Http2FrameReader frameReader,
      final Http2PromisedRequestVerifier requestVerifier,
      final boolean autoAckSettings); @Override void lifecycleManager(final Http2LifecycleManager lifecycleManager); @Override Http2Connection connection(); @Override final Http2LocalFlowController flowController(); @Override void frameListener(final Http2FrameListener listener); @Override Http2FrameListener frameListener(); @Override boolean prefaceReceived(); @Override void decodeFrame(final ChannelHandlerContext ctx, final ByteBuf in, final List<Object> out); @Override Http2Settings localSettings(); @Override void close();  }### Answer:
@Test public void errorDuringDeliveryShouldReturnCorrectNumberOfBytes() throws Exception { final ByteBuf data = dummyData(); final int padding = 10; final AtomicInteger unprocessed = new AtomicInteger(data.readableBytes() + padding); doAnswer( new Answer<Integer>() { @Override public Integer answer(final InvocationOnMock in) throws Throwable { return unprocessed.get(); } }) .when(localFlow) .unconsumedBytes(eq(stream)); doAnswer( new Answer<Void>() { @Override public Void answer(final InvocationOnMock in) throws Throwable { final int delta = (Integer) in.getArguments()[1]; final int newValue = unprocessed.addAndGet(-delta); if (newValue < 0) { throw new RuntimeException("Returned too many bytes"); } return null; } }) .when(localFlow) .consumeBytes(eq(stream), anyInt()); doAnswer( new Answer<Integer>() { @Override public Integer answer(final InvocationOnMock in) throws Throwable { localFlow.consumeBytes(stream, 4); throw new RuntimeException("Fake Exception"); } }) .when(listener) .onDataRead(eq(ctx), eq(STREAM_ID), any(ByteBuf.class), eq(10), eq(true)); try { decode().onDataRead(ctx, STREAM_ID, data, padding, true); fail("Expected exception"); } catch (final RuntimeException cause) { verify(localFlow).receiveFlowControlledFrame(eq(stream), eq(data), eq(padding), eq(true)); verify(lifecycleManager).closeStreamRemote(eq(stream), eq(future)); verify(listener).onDataRead(eq(ctx), eq(STREAM_ID), eq(data), eq(padding), eq(true)); assertEquals(0, localFlow.unconsumedBytes(stream)); } finally { data.release(); } }