为什么 @Cachable(...) 可以与 @Bean return mock() 一起使用,但不能与 @MockedBean 一起使用

Nic*_* S. 4 mockito spring-bean spring-boot spring-cache spring-boot-test

为什么使用时缓存会被值填满

@Autowired
ServiceXY serviceXY

@TestConfiguration
static class AppDefCachingTestConfiguration {
    @Bean
    public ServiceXY ServiceXYMock() {
        return mock(ServiceXY.class);
    }
}
Run Code Online (Sandbox Code Playgroud)

但不与

@MockBean
ServiceXY serviceXY
Run Code Online (Sandbox Code Playgroud)

使用 @MockBean 时,在访问缓存值时会出现 NullPointerException,如我的测试中所示:

@Autowired
ConcurrentMapCacheManager cmcm; 

@Test
void anTest(){
when(serviceXY.methodThatFillsCache(anyString()).thenReturn("ABC");

serviceXY.methodThatFillsCache("TEST1");

cmcm.getCache("Cachename").get("TEST1",String.class).equals("ABC");
...
}
Run Code Online (Sandbox Code Playgroud)

And*_*son 5

缓存是使用代理来实现的,该代理拦截对可缓存方法的调用。当您使用 时@MockBean,Spring Boot会故意禁用代理。这样做的后果之一是不执行缓存。最近有人指出,这没有很好的记录,因此我们将来可能会更新文档。

如果您想测试缓存是否按预期工作,您应该使用服务的真正实现,或者通过方法自行创建模拟,@Bean就像您在问题的第一个示例中所做的那样。