1

I'm trying to test my cache layer with mockito.

I'm using Caffeine as described here

Basically, I have this...

@Service
class Catalog {

  @Autowired
  Db db;

  @Cachable
  public List<Item> getItems() {
    // fetch from db
    db.someDbMethod();
  }
}

@Configuration
@EnableCaching
class CatalogConfig {
  @Bean
  public CacheManager cacheManager() {
    return new CaffeineCacheManager();
  }
  @Bean
  public Db db() {
     return new Db();
  }
}
// properties as in documentation etc

That works perfectly, the method is cached and works fine.

I want to add a test to verify the DB call is invoked only once, I have something like this but it's not working:

public class CatalogTest {

     @Mock
     Db db;

     @InjectMocks
     Catalog catalog;

     // init etc

     @Test
     void cache() {
       catalog.getItems();
       catalog.getItems();
       verify(db, times(1)).someDbMethod(); // fails... expected 1 got 2
     }
     // Some other passing tests below
     @Test
     void getItems() {
       assertNotNull(catalog.getItems()); // passes
     }
}

I've tried several combinations of @Profile/@ActiveProfile, Config/ContextConfiguration etc.

4

1 回答 1

1

我有这个案子。我通过部分 bean 的导入来解决它SpringJUnit4ClassRunner:我将尝试编写主要思想:

@RunWith(SpringJUnit4ClassRunner.class)
@Import({CaffeineCacheManager.class, Catalog.class})
public class CatalogTest {

@MockBean
private Db db;

@Autowired
private CaffeineCacheManager cache;

@Autowired
private Catalog catalog;

@Test
void cacheTest(){
   when(db.someDbMethod()).thenReturn(....);

   catalog.getItems();
   catalog.getItems();

   verify(db, times(1)).someDbMethod();

   assertTrue(cache.get(SOME_KEY).isPresent());//if you want to check that cache contains your entity
}

}

您将拥有真正的缓存 bean 并有机会检查调用模拟 Db 的时间,并且您还可以在测试中获取缓存键。

于 2021-02-19T16:26:32.387 回答