我的单元测试问题 - Junit - mockito - EntityManager - createNativeQuery

Posted

技术标签:

【中文标题】我的单元测试问题 - Junit - mockito - EntityManager - createNativeQuery【英文标题】:Issue with my unit testing - Junit - mockito - EntityManager - createNativeQuery 【发布时间】:2021-05-28 12:18:45 【问题描述】:

我正在尝试测试使用 createNativeQuery 查询数据库的类

这是我用来查询数据库的类。

@component
public class QueryAdapter
...    

     public UtilityResponse getCreditLimit(String id) 
         Query q = entityManager.createNativeQuery("select name from MY_TABLE where id=:id");
 
         LOGGER.info(id);
 
         q.setParameter("id", id);
         q.setMaxResults(Integer.parseInt(env.getProperty("maxrows")));
 
         @SuppressWarnings("unchecked")
         List<Object[]> d = q.getResultList();
 
         UtilityResponse duresp = new UtilityResponse();
         duresp.setData(d);
 
         return duresp;
...

我已经编写了一个如下所示的 junit 测试类。我嘲笑了 EntityManager 和 Query 类。当遇到 getResultList 方法时,我希望从 getResponse() 方法返回 List

 package com.myorg.myapp.datautility.test;
 
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.when;
 import static org.mockito.ArgumentMatchers.any;
 
 import java.util.ArrayList;
 import java.util.List;
 
 import javax.persistence.EntityManager;
 import javax.persistence.Query;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.junit4.SpringRunner;
 
 import com.myorg.myapp.datautility.adapter.QueryAdapter;
 
 @SpringBootTest
 @RunWith(SpringRunner.class)
 public class UtilityAdapterTest 
     
     @Mock
     EntityManager em;
     
     @Autowired
     public QueryAdapter dqa;
     
     @Mock
     Query mockedQuery;
     
     @Test
     public void getCreditLimitTest() 
         String id = "12345";
         
         when(em.createNativeQuery(any(String.class))).thenReturn(mockedQuery);
         Mockito.when(em.createNativeQuery(Mockito.anyString())).thenReturn(mockedQuery);
         when(mockedQuery.getResultList()).thenReturn(getResponse());
 
         UtilityResponse dur=dqa.getCreditLimit(id);
         
         assertTrue(dur instanceof UtilityResponse);
 
     
 
     public List<Object[]> getResponse() 
         List<Object[]> lo = new ArrayList<>();
         
         Object[] os = new Object[6];
 
         for (int i = 0; i < 6; i++) 
             os[i] = "STUB";
         
 
         lo.add(os);
 
         return lo;
     
 
 

我的 application.properties 是这样的。我实际上使用的是 h2 数据库。

 server.port=8004
 
 spring.jpa.show-sql=true
 
 spring.jpa.properties.hibernate.generate_statistics=false
 spring.datasource.url=jdbc:h2:mem:temp;DB_CLOSE_DELAY=-1
 spring.datasource.username=sa
 spring.datasource.password=
 spring.datasource.driver-class-name=org.h2.Driver
 spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
 spring.jpa.hibernate.ddl-auto=none

当我运行测试用例时,我期待一个成功的结果。但我得到以下结果。这是我要访问的表

2021-02-25 23:33:19.084  WARN 36008 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 42102, SQLState: 42S02
2021-02-25 23:33:19.084 ERROR 36008 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : Table "MY_TABLE" not found; SQL statement

【问题讨论】:

1. SpringBootTest 会忽略您的模拟。 2 向我们展示 QueryAdapter,特别是实体管理器是如何初始化的。 【参考方案1】:

你必须将你的模拟注入你试图测试的类。

代替

 @Autowired
 public QueryAdapter dqa;

试试这个:

 @InjectMocks
 public QueryAdapter dqa;

请参考这篇文章了解更多:https://howtodoinjava.com/mockito/mockito-mock-injectmocks/

【讨论】:

在我将其更改为 ___ @InjectMocks public QueryAdapter dqa;___ 我在步骤____ Query q = entityManager.createNativeQuery("select name from MY_TABLE where id=:id") 中得到一个空指针异常;__________ q 实际上为空 您可以尝试使用@RunWith(MockitoJunitRunner.class) 或者如果您不想更改跑步者,请尝试在您的原始实现中使用@MockBean 而不是@Mock(使用@Autowired)参考:@ 987654322@

以上是关于我的单元测试问题 - Junit - mockito - EntityManager - createNativeQuery的主要内容,如果未能解决你的问题,请参考以下文章

在 Spring Boot 应用程序中运行 JUnit 单元测试而不提供数据源

使用 spring boot、kotlin 和 junit 进行休息控制器单元测试

使用 JUnit (Java) 的 Selenium 单元测试

Junit单元测试

Mockito 如何模拟和断言抛出的异常?

Java测试框架——JUnit详解(4&5)