我的缓存配置如下;
@Configuration
public class CacheConfiguration {
@Bean
public CacheManager cacheManager(Ticker ticker) {
CaffeineCache bookCache = buildCache("books", ticker, 30);
SimpleCacheManager cacheManager = new SimpleCacheManager();
cacheManager.setCaches(Collections.singletonList(bookCache));
return cacheManager;
}
private CaffeineCache buildCache(String name, Ticker ticker, int minutesToExpire) {
return new CaffeineCache(name, Caffeine.newBuilder()
.expireAfterWrite(minutesToExpire, TimeUnit.MINUTES)
.maximumSize(100)
.ticker(ticker)
.build());
}
@Bean
public Ticker ticker() {
return Ticker.systemTicker();
}
}
我要测试的服务:
@Service
public class TestServiceImpl implements TestService {
private final BookRepository bookRepository; // interface
@Autowired
public TestServiceImpl(final BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
@Override
public Book getByIsbn(String isbn) {
return bookRepository.getByIsbn(isbn);
}
}
存储库中所需的方法用@Cacheable("books")
.
@Override
@Cacheable("books")
public Book getByIsbn(String isbn) {
LOGGER.info("Fetching Book...");
simulateSlowService(); // Wait for 5 secs
return new Book(isbn, "Some book");
}
我需要编写一个显示缓存工作的测试。所以我ticker
在测试中创建了另一个 bean 来覆盖CacheConfiguration
. 编码;
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestServiceTests {
private static final String BOOK_ISBN = "isbn-8442";
@SpyBean
private BookRepository bookRepository;
@Autowired
private TestService testService;
@Configuration
@Import(SpringBootCacheApplication.class)
public static class TestConfiguration {
//testCompile('com.google.guava:guava-testlib:23.6-jre')
static FakeTicker fakeTicker = new FakeTicker();
@Bean
public Ticker ticker() {
return fakeTicker::read;
}
}
@Before
public void setUp() {
Book book = fakeBook();
doReturn(book)
.when(bookRepository)
.getByIsbn(BOOK_ISBN);
}
private Book fakeBook() {
return new Book(BOOK_ISBN, "Mock Book");
}
@Test
public void shouldUseCache() {
// Start At 0 Minutes
testService.getByIsbn(BOOK_ISBN);
verify(bookRepository, times(1)).getByIsbn(BOOK_ISBN);
// After 5 minutes from start, it should use cached object
TestConfiguration.fakeTicker.advance(5, TimeUnit.MINUTES);
testService.getByIsbn(BOOK_ISBN);
verify(bookRepository, times(1)).getByIsbn(BOOK_ISBN); // FAILS HERE
// After 35 Minutes from start, it should call the method again
TestConfiguration.fakeTicker.advance(30, TimeUnit.MINUTES);
testService.getByIsbn(BOOK_ISBN);
verify(bookRepository, times(2)).getByIsbn(BOOK_ISBN);
}
}
但它在标有//FAILS HERE
消息的行处失败;
org.mockito.exceptions.verification.TooManyActualInvocations:
simpleBookRepository.getByIsbn("isbn-8442");
Wanted 1 time:
-> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
But was 2 times. Undesired invocation:
-> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
为什么会失败?它不应该使用缓存吗?还是我的测试错了?
非常感谢任何帮助或指示!:)