Java Redis缓存单元测试不生效,如何基于最新依赖版本修复测试逻辑
问题根源
缓存基于Spring AOP代理实现,你的测试配置没有让Spring接管Service实例的创建,缓存切面无法生效:
- 测试类使用
MockitoExtension而非SpringExtension,Spring相关注解(@EnableCaching、@Autowired、自动配置)完全不生效 @InjectMocks创建的是普通的Service实例,没有被AOP代理包裹,调用方法不会触发缓存逻辑- 额外确认:你的业务代码
findByUuid方法上必须添加@Cacheable(cacheNames = "demoCache", key = "#uuid")注解,这是缓存生效的前提
修正方案
使用Spring Boot切片测试加载必要上下文,让Spring创建代理后的Service实例:
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.CacheManager; @SpringBootTest @EnableCaching @ImportAutoConfiguration(classes = { CacheAutoConfiguration.class, RedisAutoConfiguration.class }) @ExtendWith(SpringExtension.class) class TextLabelServiceImpl_deneme_Test { @Autowired private CacheManager cacheManager; @Autowired // 这里不再用@InjectMocks,由Spring创建代理后的实例 private LabelService labelService; @MockBean // 用@MockBean替换@Mock,把Mock对象注册到Spring上下文 private LabelRepository labelRepository; @MockBean private LabelTranslatableRepository translatableRepository; @Test void test_Cache() { UUID uuid = UUID.randomUUID(); final TextLabel textLabel = new TextLabel(); textLabel.setId(1); textLabel.setKey("key1"); textLabel.setUuid(uuid); // 注意补全uuid属性赋值 TextLabelTranslatable textLabelTranslatable = new TextLabelTranslatable(); textLabelTranslatable.setEntityUuid(uuid); textLabelTranslatable.setLanguage(SupportedLanguage.fr); textLabelTranslatable.setValue("value1"); final List<TextLabelTranslatable> translatableList = new ArrayList<>(); translatableList.add(textLabelTranslatable); when(labelRepository.findByUuid(uuid)).thenReturn(Optional.of(textLabel)); when(translatableRepository.findAllByEntityUuid(uuid)).thenReturn(translatableList); TextLabelDTO result1 = labelService.findByUuid(uuid); TextLabelDTO result2 = labelService.findByUuid(uuid); assertEquals(result1, result2); // 验证调用次数为1,缓存生效 Mockito.verify(translatableRepository, Mockito.times(1)).findAllByEntityUuid(uuid); } }
额外注意项
- 确保
LabelDTO已经正确重写equals和hashCode方法,否则结果对比会失败 - 如果不需要加载完整Spring上下文,可以用
@SpringBootTest(classes = {LabelServiceImpl.class, CacheAutoConfiguration.class, RedisAutoConfiguration.class})缩小加载范围,提升测试速度 - 测试执行后可以手动校验缓存内容:
Assertions.assertNotNull(cacheManager.getCache("demoCache").get(uuid).get());
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

