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

Spring Boot JUnit中Mock CacheManager时触发NullPointerException问题

问题分析与解决方案

核心问题点

  1. Mockito语法错误:doReturn(...).when(mock.method(...)) 这种写法会直接执行mock.method(...),此时mock的依赖未正确设置,直接触发NPE。正确写法是doReturn(...).when(mock).method(...)。
  2. 测试初始化冲突:使用@RunWith(MockitoJUnitRunner.class)时,无需再调用openMocks(this),重复初始化会导致mock失效。
  3. 变量名拼写错误:代码中存在userDispte、cacheManger等拼写错误,导致变量引用异常。
  4. 参数匹配器不匹配:loadCache方法接收两个参数,但测试中只使用了一个anyString(),无法正确匹配方法调用。
  5. 未定义必要mock对象:valueWrapper未被mock,缺少对应的Mock声明。

修正后的测试代码

// 改用MockitoExtension适配JUnit 5,替代JUnitRunner
@ExtendWith(MockitoExtension.class)
public class UserDisputeTest {
    
    @InjectMocks
    private UserDispute userDispute; // 修正拼写错误
  
    @Mock
    private Cache cacheMock;
   
    @Mock
    private CacheManager cacheManagerMock;
   
    @Mock
    private CacheContextConfig cacheContextConfigMock;

    @Mock
    private ValueWrapper valueWrapperMock; // 添加ValueWrapper的Mock

    @Test // 必须添加@Test注解,否则测试方法不会执行
    public void testManageUserDisputeData() {
        // 正确的Mockito语法:先指定mock对象,再指定方法
        doReturn(cacheMock).when(cacheManagerMock).getCache(anyString(), any());
        doReturn(valueWrapperMock).when(cacheContextConfigMock).loadCache(anyString(), any()); 
        
        String actualResult = userDispute.manageUserDisputeData();
        
        // 示例断言:验证方法调用次数
        verify(cacheContextConfigMock, times(1)).loadCache("userStore", "userKey");
        // 补充其他业务逻辑断言
    }
} 

额外优化方案

如果想测试CacheContextConfig的真实逻辑而非完全mock,可以用@Spy注入真实对象,仅mock其依赖的CacheManager:

@ExtendWith(MockitoExtension.class)
public class UserDisputeTest {
    
    @InjectMocks
    private UserDispute userDispute;
  
    @Mock
    private Cache cacheMock;
   
    @Mock
    private CacheManager cacheManagerMock;
   
    @Spy // 注入真实对象,同时mock其依赖
    private CacheContextConfig cacheContextConfig;

    @Mock
    private ValueWrapper valueWrapperMock;

    @BeforeEach
    public void setup() {
        // 手动将mock的CacheManager注入到Spy对象中
        ReflectionTestUtils.setField(cacheContextConfig, "cacheManager", cacheManagerMock);
    }

    @Test
    public void testManageUserDisputeData() {
        doReturn(cacheMock).when(cacheManagerMock).getCache(anyString(), any());
        doReturn(valueWrapperMock).when(cacheMock).get(any()); // 模拟Cache的get方法
        
        String actualResult = userDispute.manageUserDisputeData();
        
        verify(cacheManagerMock, times(1)).getCache("userStore", "userKey");
    }
}

内容的提问来源于stack exchange,提问作者Naresh Developer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 20:32:37