private static Pair<PTFPartition, ValueBoundaryScanner> setupMocks(
          LinkedList<List<IntWritable>> partition, int orderByCol, BoundaryDef start, BoundaryDef end,
          PTFInvocationSpec.Order order, BoundaryCache cache,
          AtomicInteger readCounter) throws Exception {
    PTFPartition partitionMock = mock(PTFPartition.class);
    doAnswer(invocationOnMock -> {
      int idx = invocationOnMock.getArgument(0, Integer.class);
      return partition.get(idx);
    }).when(partitionMock).getAt(any(Integer.class));
    doAnswer(invocationOnMock -> {
      return partition.size();
    }).when(partitionMock).size();
    when(partitionMock.getBoundaryCache()).thenReturn(cache);

    OrderExpressionDef orderDef = mock(OrderExpressionDef.class);
    when(orderDef.getOrder()).thenReturn(order);

    ValueBoundaryScanner scan = new LongValueBoundaryScanner(start, end, orderDef, order == ASC);
    ValueBoundaryScanner scannerSpy = spy(scan);
    doAnswer(invocationOnMock -> {
      readCounter.incrementAndGet();
      List<IntWritable> row = invocationOnMock.getArgument(0, List.class);
      return row.get(orderByCol);
    }).when(scannerSpy).computeValue(any(Object.class));
    doAnswer(invocationOnMock -> {
      IntWritable v1 = invocationOnMock.getArgument(0, IntWritable.class);
      IntWritable v2 = invocationOnMock.getArgument(1, IntWritable.class);
      return (v1 != null && v2 != null) ? v1.get() == v2.get() : v1 == null && v2 == null;
    }).when(scannerSpy).isEqual(any(Object.class), any(Object.class));
    doAnswer(invocationOnMock -> {
      IntWritable v1 = invocationOnMock.getArgument(0, IntWritable.class);
      IntWritable v2 = invocationOnMock.getArgument(1, IntWritable.class);
      Integer amt = invocationOnMock.getArgument(2, Integer.class);
      return (v1 != null && v2 != null) ? (v1.get() - v2.get()) > amt :  v1 != null || v2 != null;
    }).when(scannerSpy).isDistanceGreater(any(Object.class), any(Object.class), any(Integer.class));

    setOrderOnTestPartitions(partition, order);
    return new ImmutablePair<>(partitionMock, scannerSpy);

  }
Sets up mock and spy objects used for testing.
@param partition The real partition containing row values.
@param orderByCol Index of column in the row used for separating ranges.
@param start Window definition.
@param end Window definition.
@param order Window definition.
@param cache BoundaryCache instance, it may come in various sizes.
@param readCounter counts how many times reading was invoked
@return Mocked PTFPartition instance and ValueBoundaryScanner spy.
@throws Exception
ql/src/test/org/apache/hadoop/hive/ql/udf/ptf/TestBoundaryCache.java