Spring Boot JUnit中Mock CacheManager时触发NullPointerException问题
问题分析与解决方案
核心问题点
- Mockito语法错误:
doReturn(...).when(mock.method(...))这种写法会直接执行mock.method(...),此时mock的依赖未正确设置,直接触发NPE。正确写法是doReturn(...).when(mock).method(...)。 - 测试初始化冲突:使用
@RunWith(MockitoJUnitRunner.class)时,无需再调用openMocks(this),重复初始化会导致mock失效。 - 变量名拼写错误:代码中存在
userDispte、cacheManger等拼写错误,导致变量引用异常。 - 参数匹配器不匹配:
loadCache方法接收两个参数,但测试中只使用了一个anyString(),无法正确匹配方法调用。 - 未定义必要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
相关产品推荐
相关产品推荐

