private void runAsserts(CachingEntitySelector entitySelector) {
   Iterator<Object> iterator = entitySelector.iterator();
   assertNotNull(iterator);
   assertTrue(iterator.hasNext());
   assertCode("e1", iterator.next());
   assertTrue(iterator.hasNext());
   assertCode("e2", iterator.next());
   assertTrue(iterator.hasNext());
   assertCode("e3", iterator.next());
   assertFalse(iterator.hasNext());
   assertEquals(false, entitySelector.isContinuous());
   assertEquals(false, entitySelector.isNeverEnding());
   assertEquals(3L, entitySelector.getSize());
 }
  public void runCacheType(SelectionCacheType cacheType, int timesCalled) {
    EntitySelector childEntitySelector =
        SelectorTestUtils.mockEntitySelector(
            TestdataEntity.class,
            new TestdataEntity("e1"),
            new TestdataEntity("e2"),
            new TestdataEntity("e3"));

    CachingEntitySelector entitySelector =
        new CachingEntitySelector(childEntitySelector, cacheType);
    verify(childEntitySelector, times(1)).isNeverEnding();

    DefaultSolverScope solverScope = mock(DefaultSolverScope.class);
    entitySelector.solvingStarted(solverScope);

    AbstractSolverPhaseScope phaseScopeA = mock(AbstractSolverPhaseScope.class);
    when(phaseScopeA.getSolverScope()).thenReturn(solverScope);
    entitySelector.phaseStarted(phaseScopeA);

    AbstractStepScope stepScopeA1 = mock(AbstractStepScope.class);
    when(stepScopeA1.getSolverPhaseScope()).thenReturn(phaseScopeA);
    entitySelector.stepStarted(stepScopeA1);
    runAsserts(entitySelector);
    entitySelector.stepEnded(stepScopeA1);

    AbstractStepScope stepScopeA2 = mock(AbstractStepScope.class);
    when(stepScopeA2.getSolverPhaseScope()).thenReturn(phaseScopeA);
    entitySelector.stepStarted(stepScopeA2);
    runAsserts(entitySelector);
    entitySelector.stepEnded(stepScopeA2);

    entitySelector.phaseEnded(phaseScopeA);

    AbstractSolverPhaseScope phaseScopeB = mock(AbstractSolverPhaseScope.class);
    when(phaseScopeB.getSolverScope()).thenReturn(solverScope);
    entitySelector.phaseStarted(phaseScopeB);

    AbstractStepScope stepScopeB1 = mock(AbstractStepScope.class);
    when(stepScopeB1.getSolverPhaseScope()).thenReturn(phaseScopeB);
    entitySelector.stepStarted(stepScopeB1);
    runAsserts(entitySelector);
    entitySelector.stepEnded(stepScopeB1);

    AbstractStepScope stepScopeB2 = mock(AbstractStepScope.class);
    when(stepScopeB2.getSolverPhaseScope()).thenReturn(phaseScopeB);
    entitySelector.stepStarted(stepScopeB2);
    runAsserts(entitySelector);
    entitySelector.stepEnded(stepScopeB2);

    AbstractStepScope stepScopeB3 = mock(AbstractStepScope.class);
    when(stepScopeB3.getSolverPhaseScope()).thenReturn(phaseScopeB);
    entitySelector.stepStarted(stepScopeB3);
    runAsserts(entitySelector);
    entitySelector.stepEnded(stepScopeB3);

    entitySelector.phaseEnded(phaseScopeB);

    entitySelector.solvingEnded(solverScope);

    verify(childEntitySelector, times(1)).solvingStarted(solverScope);
    verify(childEntitySelector, times(2)).phaseStarted(Matchers.<AbstractSolverPhaseScope>any());
    verify(childEntitySelector, times(5)).stepStarted(Matchers.<AbstractStepScope>any());
    verify(childEntitySelector, times(5)).stepEnded(Matchers.<AbstractStepScope>any());
    verify(childEntitySelector, times(2)).phaseEnded(Matchers.<AbstractSolverPhaseScope>any());
    verify(childEntitySelector, times(1)).solvingEnded(solverScope);
    verify(childEntitySelector, times(timesCalled)).iterator();
    verify(childEntitySelector, times(timesCalled)).getSize();
  }