ChainCellRouter implements CellRouter { @Override public Optional<Cell> routeKey(JobDescriptor jobDescriptor) { for (CellRouter cellRouter : cellRouters) { Optional<Cell> result = cellRouter.routeKey(jobDescriptor); if (result.isPresent()) { return result; } } return Optional.empty(); } ChainCellRouter(List<CellRouter> cellRouters); @Override Optional<Cell> routeKey(JobDescriptor jobDescriptor);  }
@Test public void testChaining() { CellRouter first = Mockito.mock(CellRouter.class); CellRouter second = Mockito.mock(CellRouter.class); ChainCellRouter chain = new ChainCellRouter(asList(first, second)); when(first.routeKey(any())).thenReturn(Optional.empty()); when(second.routeKey(any())).thenReturn(Optional.empty()); assertThat(chain.routeKey(JobDescriptor.getDefaultInstance())).isEmpty(); when(first.routeKey(any())).thenReturn(Optional.of(CELL_1)); when(second.routeKey(any())).thenReturn(Optional.of(CELL_2)); assertThat(chain.routeKey(JobDescriptor.getDefaultInstance())).contains(CELL_1); when(first.routeKey(any())).thenReturn(Optional.empty()); when(second.routeKey(any())).thenReturn(Optional.of(CELL_2)); assertThat(chain.routeKey(JobDescriptor.getDefaultInstance())).contains(CELL_2); }