You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 11:15:04