使用mockito进行单元测试搜索方法(querydsl)

问题描述 投票:0回答:1

在我的 springboot 应用程序中,我尝试使用mockito 为我的搜索方法编写单元测试:

服务:

QRental qRental = QRental.rental;
        var jpaQuery = new JPAQuery<Rental>(entityManager)
                .select(qRental)
                .from(qRental);


        if (reason != null && !reason.isBlank()) {
            jpaQuery = jpaQuery.where(qRental.reason.likeIgnoreCase(reason));
        }

        var result = jpaQuery.fetch();
        return rentalMapper.toDtos(result);

测试:

@ExtendWith(MockitoExtension.class)
class RentalServiceImplTest {

    
    @Mock
    private JPAQuery<Rental> jpaQuery;


    @Mock
    private EntityManager entityManager;

    @Mock
    private QRental qRental;

    @InjectMocks
    private RentalServiceImpl rentalService;

    @Test
    void searchRentals() {


        when(jpaQuery.select()).thenReturn(new JPAQuery<>());
        when(jpaQuery.from()).thenReturn(new JPAQuery<>());
        when(jpaQuery.where()).thenReturn(new JPAQuery<>());

do more stuff...

我收到此错误:

java.lang.NullPointerException: Cannot invoke "javax.persistence.EntityManagerFactory.getProperties()" because the return value of "javax.persistence.EntityManager.getEntityManagerFactory()" is null

    at com.querydsl.jpa.impl.JPAProvider.getTemplates(JPAProvider.java:94)
    at com.querydsl.jpa.impl.JPAQuery.<init>(JPAQuery.java:48)

我认为问题与 EntityManager 初始化有关,但我不能 100% 确定。 有人可以帮忙吗???如果需要更多信息,我很乐意提供:) 预先感谢!

我想模拟 RentalServiceImpl 中使用的 querydsl,以便它返回用于测试的预定义租赁实体列表。

spring-boot junit mockito querydsl entitymanager
1个回答
0
投票

首先,模拟 DB API 并不是测试数据库查询的有效方法。

  • 您严重依赖 DB Access 库内部结构
  • 您不太可能发现任何语法错误

相反,你应该:

  • 配置您的测试以在您的计算机上启动数据库。理想情况下,使用与 PROD 相同的引擎。
  • 这可以是嵌入式数据库,或者在 Docker 中运行
  • 您可以退回到 H2,这是设置最快的,但与 PROD 引擎的差异最终会让您感到困扰。
  • 使用 Spring-Boots
    DataJpaTest
    针对此数据库测试您的数据访问组件
  • 请注意,DataJpaTest 默认使用 H2,配置您的测试以禁用此行为

对于你原来的问题:

JPAProvider.getTemplates

的实现
// detect by properties
for (String key : em.getEntityManagerFactory().getProperties().keySet()) {
    key = key.toLowerCase();
    for (Map.Entry<String, JPQLTemplates> entry : templatesByName.entrySet()) {
        if (key.contains(entry.getKey())) {
            return entry.getValue();
        }
    }
}

很可能 hou 缺少

em.getEntityManagerFactory().getProperties().keySet()
链中方法之一的存根,因此 Mockito 返回默认值 va,ue,即 null。

© www.soinside.com 2019 - 2024. All rights reserved.