### Question:
RatesProviderService { protected Optional<ExchangeAggregateRate> getClosestRateToTimestamp(Instant timestamp, List<ExchangeAggregateRate> rates) { if (rates == null || rates.isEmpty()) { return Optional.empty(); } else { return ofNullable(Collections.min(rates, new Comparator<ExchangeAggregateRate>() { public int compare(ExchangeAggregateRate rate1, ExchangeAggregateRate rate2) { long time1 = rate1.getCreationDate() != null ? rate1.getCreationDate().getTime() : 0; long time2 = rate2.getCreationDate() != null ? rate2.getCreationDate().getTime() : 0; long diff1 = Math.abs(time1 - timestamp.toEpochMilli()); long diff2 = Math.abs(time2 - timestamp.toEpochMilli()); return Long.compare(diff1, diff2); } })); } }  BigDecimal getLatestFromDB(CurrencyType currencyType); BigDecimal getRate(CurrencyType currencyType, Instant timestamp); static Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor);  }### Answer:
@Test public void testGetClosestRateToTimestamp_TwoEntriesWithSameDifferenceShouldGetTheHigherOne() { Instant now = Instant.now(); List<ExchangeAggregateRate> rates = Arrays.asList( createExchangeAggregateRate(Date.from(now.plusSeconds(1))), createExchangeAggregateRate(Date.from(now.minusSeconds(1))) ); Optional<ExchangeAggregateRate> closestRate = ratesProviderService.getClosestRateToTimestamp(now, rates); assertTrue(closestRate.isPresent()); assertTrue(now.isBefore(closestRate.get().getCreationDate().toInstant())); }
@Test public void testGetClosestRateToTimestamp_OneEntryOnly() { Instant now = Instant.now(); List<ExchangeAggregateRate> rates = Arrays.asList( createExchangeAggregateRate(Date.from(now.plusSeconds(1))) ); Optional<ExchangeAggregateRate> closestRate = ratesProviderService.getClosestRateToTimestamp(now, rates); assertTrue(closestRate.isPresent()); assertTrue(now.isBefore(closestRate.get().getCreationDate().toInstant())); }
@Test public void testGetClosestRateToTimestamp_NoEntries() { Instant now = Instant.now(); List<ExchangeAggregateRate> rates = Arrays.asList(); Optional<ExchangeAggregateRate> closestRate = ratesProviderService.getClosestRateToTimestamp(now, rates); assertTrue(!closestRate.isPresent()); }
@Test public void testGetClosestRateToTimestamp_EntriesWithNullCreationDate() { Instant now = Instant.now(); List<ExchangeAggregateRate> rates = Arrays.asList( createExchangeAggregateRate(Date.from(now.plusSeconds(5))), createExchangeAggregateRate(Date.from(now.plusSeconds(1))), createExchangeAggregateRate(null), createExchangeAggregateRate(null), createExchangeAggregateRate(Date.from(now.minusSeconds(1))) ); Optional<ExchangeAggregateRate> closestRate = ratesProviderService.getClosestRateToTimestamp(now, rates); assertTrue(closestRate.isPresent()); assertNotNull(closestRate.get().getCreationDate()); assertTrue(now.isBefore(closestRate.get().getCreationDate().toInstant())); }