JPA访问Root嵌套对象报NullPointerException的Mockito测试如何解决
空指针原因说明
你遇到的空指针是因为自定义的Root匿名实现中,get(String s)方法直接返回null,执行root.get("object1")后得到的是空值,后续再调用.get("object2")自然触发空指针。你自己手写Root、CriteriaBuilder等接口的匿名实现效率低,也容易出现这类漏处理的问题,直接用Mockito mock对应接口即可,不需要额外实现所有方法。
解决步骤
- 替换所有手写的接口匿名实现为Mockito Mock对象,不用手动实现接口的全部方法
- 为嵌套的Path调用链配置Mock返回值,保证每一级
get调用都能拿到非空的Mock Path对象 - 为CriteriaBuilder用到的
upper、like、and方法配置返回值
完整测试示例代码
import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import javax.persistence.criteria.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class HibPaginationTest { @InjectMocks private HibPagination pagn; @Mock private Root<?> root; @Mock private Filter filter; @Mock private CriteriaBuilder cb; @Mock private Predicate where; @Mock private Path object1Path; @Mock private Path object2Path; @Mock private Path dataMemberPath; @Mock private Expression<String> upperExp; @Mock private Predicate mockPredicate; @Test public void buildXYZQueryTest() { // 配置嵌套get调用的返回值 when(root.get("object1")).thenReturn(object1Path); when(object1Path.get("object2")).thenReturn(object2Path); when(object2Path.get("DataMember_Of_Object2_Returning_String_Value")).thenReturn(dataMemberPath); // 配置CriteriaBuilder方法的返回值 when(cb.upper(any(Expression.class))).thenReturn(upperExp); when(cb.like(eq(upperExp), anyString())).thenReturn(mockPredicate); when(cb.and(any(Predicate.class), any(Predicate.class), any(Predicate.class))).thenReturn(mockPredicate); // 执行测试方法 Predicate result = pagn.buildXYZQuery(root, filter, cb, where, "test_user"); // 可自行添加断言验证结果符合预期 } }
如果需要验证方法的调用逻辑是否正确,还可以用Mockito的verify方法验证对应方法的调用次数、参数是否符合预期。
内容的提问来源于stack exchange,提问作者Aniruddh Dwivedi
相关产品推荐
相关产品推荐

