71 lines
2.7 KiB
Java
71 lines
2.7 KiB
Java
package com.ankurm.distributedcache;
|
|
|
|
import org.junit.jupiter.api.Test;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat;
|
|
|
|
/**
|
|
* The same two behaviours, asserted identically, against whichever
|
|
* CacheManager the active Spring profile wired up. That's deliberate:
|
|
* the point of the Spring Cache abstraction is that ExchangeRateLookupService
|
|
* and this test never change when the backend does - only the
|
|
* subclass's @ActiveProfiles (and, for Redis, the container) changes.
|
|
*
|
|
* ExchangeRateLookupService's callCount() is a singleton counter shared
|
|
* across every @Test method in a subclass's Spring context (JUnit does
|
|
* not create a fresh context per test method), so each test reads the
|
|
* counter before and after its own calls and asserts the *delta* rather
|
|
* than an absolute value - that way test execution order inside one
|
|
* class can never affect the result.
|
|
*/
|
|
abstract class CacheHitAndEvictionContractTest {
|
|
|
|
@Autowired
|
|
ExchangeRateLookupService service;
|
|
|
|
abstract String backendName();
|
|
|
|
@Test
|
|
void secondCallForSameKeyIsServedFromCache() {
|
|
int before = service.callCount();
|
|
|
|
service.rateFor("USD/INR");
|
|
int afterFirstCall = service.callCount();
|
|
|
|
service.rateFor("USD/INR");
|
|
int afterSecondCall = service.callCount();
|
|
|
|
Transcript t = new Transcript("29-" + backendName() + "-cache-hit.txt");
|
|
t.line("backend=%s", backendName());
|
|
t.line("rateFor(\"USD/INR\") call 1 -> method body ran, callCount %d -> %d", before, afterFirstCall);
|
|
t.line("rateFor(\"USD/INR\") call 2 -> served from cache, callCount stays %d", afterSecondCall);
|
|
t.write();
|
|
|
|
assertThat(afterFirstCall).isEqualTo(before + 1);
|
|
assertThat(afterSecondCall).isEqualTo(afterFirstCall);
|
|
}
|
|
|
|
@Test
|
|
void evictingAKeyForcesTheNextCallToRecompute() {
|
|
int before = service.callCount();
|
|
|
|
service.rateFor("USD/EUR");
|
|
int afterFirstCall = service.callCount();
|
|
|
|
service.evict("USD/EUR");
|
|
service.rateFor("USD/EUR");
|
|
int afterEvictAndRecall = service.callCount();
|
|
|
|
Transcript t = new Transcript("29-" + backendName() + "-cache-evict.txt");
|
|
t.line("backend=%s", backendName());
|
|
t.line("rateFor(\"USD/EUR\") call 1 -> method body ran, callCount %d -> %d", before, afterFirstCall);
|
|
t.line("evict(\"USD/EUR\") then rateFor(\"USD/EUR\") again -> method body ran again, callCount %d -> %d",
|
|
afterFirstCall, afterEvictAndRecall);
|
|
t.write();
|
|
|
|
assertThat(afterFirstCall).isEqualTo(before + 1);
|
|
assertThat(afterEvictAndRecall).isEqualTo(afterFirstCall + 1);
|
|
}
|
|
}
|