【问题标题】:Multiselect Criteria Query returning NullPointerException in unit tests using mockito framework使用 mockito 框架在单元测试中返回 NullPointerException 的多选条件查询
【发布时间】:2021-11-29 09:20:53
【问题描述】:
@Transactional
    public List<Object[]> findAll() {
        Session session = sessionFactory.getCurrentSession();
        CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
        CriteriaQuery<Object[]> query = criteriaBuilder.createQuery(Object[].class);
        Root<TableA> aRoot = query.from(TableA.class);
        Root<TableB> bRoot = query.from(TableB.class);
        Root<TableC> cRoot = query.from(TableC.class);
        query.multiselect(aRoot.get("type"), cRoot.get("fieldId"), aRoot.get("fieldId"),
                aRoot.get("fieldId"), aRoot.get("name"), aRoot.get("name"),
                aRoot.get("average"), aRoot.get("average"));
        query.where(criteriaBuilder.equal(bRoot.get("fieldId"), cRoot.get("fieldId")),
                criteriaBuilder.in(bRoot.<String>get("type")).value("ABC").value("DFG"),<-----NullPointerException Here
                criteriaBuilder.equal(bRoot.get("type"), aRoot.get("type")));
        query.distinct(true);
       return session.createQuery(query).getResultList();
    }

这种方法已经过审查,但效果很好。我的问题是完成单元测试以覆盖代码,以便我可以推送到我们的存储库。

    @Before
    @Override
    public void setup() {
        super.setup();
    }

    @InjectMocks
    @Spy
    Dao dao;

    @Mock
    SessionFactory sessionFactory;

    @Mock
    Session mockSession;

    @Mock
    CriteriaBuilder criteriaBuilder;

    @Mock
    CriteriaQuery<Object> query;

    @Mock
    Root<TableA> mockARoot;

    @Mock
    Root<TableB> mockBRoot;

    @Mock
    Root<TableC> mockCRoot;

    @Mock
    Query<Object> result;

@Test
    public void findAll() {
        Mockito.when(sessionFactory.getCurrentSession()).thenReturn(mockSession);
        Mockito.when(mockSession.getCriteriaBuilder()).thenReturn(criteriaBuilder);
        Mockito.when(criteriaBuilder.createQuery(Mockito.anyObject())).thenReturn(query);
        Mockito.when(query.from(TableA.class)).thenReturn(mockARoot);
        Mockito.when(query.from(TableB.class)).thenReturn(mockBRoot);
        Mockito.when(query.from(TableC.class)).thenReturn(mockCRoot);
        Mockito.when(mockSession.createQuery(query)).thenReturn(result);
        dao.findAll();
    }

我相信 In 子句需要一个表达式或谓词。我是否需要模拟并传入其他接口才能使其正常工作?我真的很想将这种查询构造方式添加到我们的代码库中,但我无法完成 junit 测试。任何帮助将不胜感激!

当我调试时它说方法“Where()”没有被调用

【问题讨论】:

    标签: java hibernate jpa mockito criteria


    【解决方案1】:

    你没有模拟所有的方法调用...query.multiselect,aRoot.get("fieldId")...模拟背后的原则是你负责模拟所有需要的方法调用并定义你想要的结果。

    【讨论】:

      【解决方案2】:

      据我所知,人们不会使用 mockito 来测试 Dao 层。 它应该作为集成测试进行测试。

      关于 mockito,我们应该只在方法中使用其他类的对象(例如在您的代码中)模拟层,变量 sessionFactory 是 Dao 中此 findAll 方法中使用的其他类的对象。

      我们应该在方法(局部变量)中模拟那个类,而不是初始化它的变量。

      P.S:完整的错误堆栈跟踪将更有帮助解决这个问题。

      【讨论】:

        【解决方案3】:
        @Test
            public void findAll() {
                when(sessionFactory.getCurrentSession()).thenReturn(mockSession);
                when(mockSession.createQuery(anyString())).thenReturn(mockQuery);
                when(mockSession.getCriteriaBuilder()).thenReturn(criteriaBuilder);
                when(criteriaBuilder.createQuery(Mockito.anyObject())).thenReturn(query);
                when(query.from(TableA.class)).thenReturn(mockARoot);
                when(query.from(TableB.class)).thenReturn(mockBRoot);
                when(query.from(TableC.class)).thenReturn(mockCRoot);
                when(mockAreaRoot.get(anyString())).thenReturn(path);
                when(criteriaBuilder.in(path)).thenReturn(in);
                when(in.value(anyString())).thenReturn(in);
                when(mockSession.createQuery(query)).thenReturn(setQuery);
                dao.findAll();
                verify(dao, times(1)).findAll();
            }
        

        不是很实用,但它可以完成工作。谢谢大家的建议。

        【讨论】:

        • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
        猜你喜欢
        • 1970-01-01
        • 2020-09-10
        • 2023-03-28
        • 2023-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-03
        相关资源
        最近更新 更多