如何使用 String 和 class 作为参数为 EntityManger createNativeQuery 编写 Junit 测试用例
@Repository
public class DesignatorDaoImpl extends GenericDaoImpl implements DesignatorDao {
@Autowired
EntityManager em;
public List<Designator> getDesignators(DesignatorRequestDTO dto) throws Exception {
List<Designator> designatorsList = new ArrayList<>();
int start = dto.getStart();
String queryString ="select * from ( SELECT * FROM TAB.DESIGNATOR WHERE ACTIVE_IND ='A' ORDER BY LAST_EDITED_DATE DESC ) OFFSET "+ start +" ROWS FETCH NEXT "+dto.getLimit()+" ROWS ONLY";
Query query = em.createNativeQuery(queryString,Designator.class);
designatorsList = query.getResultList();
return designatorsList;
}
}
我有上面的类来从数据库中获取记录.我为上面的这个类编写了 JUnit 测试
I have the above class to get records from DB. I wrote JUnit test for this above class as
@Transactional
@Rollback(true)
public class DesignatorDaoImplTest {
@Mock
EntityManager entityManagerMock;
@Mock
TypedQuery<Designator> getQuery;
@InjectMocks
DesignatorDaoImpl designatorDaoImpl;
DesignatorRequestDTO dto = new DesignatorRequestDTO();
List<Designator> designatorEntityList = new ArrayList<>();
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
dto.setLimit(4);
dto.setStart(1);
Designator entity = new Designator();
entity.setId("dgbkk");
designatorEntityList.add(entity);
}
@Test
public void saveDesignatorTest() throws Exception {
Mockito.when(entityManagerMock.createNamedQuery(ArgumentMatchers.anyString(), ArgumentMatchers.eq(Designator.class))).thenReturn(getQuery);
Mockito.when(getQuery.getResultList()).thenReturn(designatorEntityList);
assertNotNull(designatorDaoImpl.saveDesignators(dto));
}
}
我在模拟时遇到问题,在 dao 类中的这个 em.createNativeQuery(queryString,Designator.class)
中,我得到了 null
.如何在测试类中正确模拟 em.createNativeQuery
?
I have problem mocking and at this em.createNativeQuery(queryString,Designator.class)
in dao class I am getting null
. How can I properly mock the em.createNativeQuery
in test class?
推荐答案
根据文档,如果你使用参数匹配器,所有参数都必须由匹配器提供.因此,请尝试使用 ArgumentMatchers.eq()
(参考文档) 检查 Designator.class
是否相等:
According to the documentation, if you are using argument matchers, all arguments have to be provided by matchers. Hence, try using ArgumentMatchers.eq()
(reference documentation) to check for Designator.class
equality:
@Mock
TypedQuery<Designator> getQuery;
@Test
public void saveDesignatorTest() throws Exception {
Mockito.when(entityManagerMock.createNamedQuery(ArgumentMatchers.anyString(), ArgumentMatchers.eq(Designator.class))).thenReturn(getQuery);
Mockito.when(getQuery.getResultList()).thenReturn(designatorEntityList);
assertNotNull(designatorDaoImpl.getDesignators(dto));
}
避免使用属性注入,而是使用构造函数注入:
Avoid using property injection and use constructor injection instead:
@Repository
public class DesignatorDaoImpl extends GenericDaoImpl implements DesignatorDao {
private EntityManager em;
public DesignatorDaoImpl(EntityManager em) {
super();
this.em = em;
}
public List<Designator> getDesignators(DesignatorRequestDTO dto) throws Exception {
List<Designator> designatorsList = new ArrayList<>();
int start = dto.getStart();
String queryString ="select * from ( SELECT * FROM TAB.DESIGNATOR WHERE ACTIVE_IND ='A' ORDER BY LAST_EDITED_DATE DESC ) OFFSET "+ start +" ROWS FETCH NEXT "+dto.getLimit()+" ROWS ONLY";
Query query = em.createNativeQuery(queryString,Designator.class);
designatorsList = query.getResultList();
return designatorsList;
}
}
然后您需要删除 @InjectMocks
因为您在初始化之前注入它们并创建 DesignatorDaoImpl
的实例以在 @Before
方法:
Then you need to drop @InjectMocks
because you are injecting them before being initialized and create the instance of DesignatorDaoImpl
to test in the @Before
method:
@Transactional
@Rollback(true)
public class DesignatorDaoImplTest {
@Mock
EntityManager entityManagerMock;
@Mock
TypedQuery<Designator> getQuery;
DesignatorDaoImpl designatorDaoImpl;
DesignatorRequestDTO dto = new DesignatorRequestDTO();
List<Designator> designatorEntityList = new ArrayList<>();
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
dto.setLimit(4);
dto.setStart(1);
Designator entity = new Designator();
entity.setId("dgbkk");
designatorEntityList.add(entity);
designatorDaoImpl = new DesignatorDaoImpl(entityManagerMock);
}
@Test
public void saveDesignatorTest() throws Exception {
Mockito.when(entityManagerMock.createNamedQuery(ArgumentMatchers.anyString(), ArgumentMatchers.eq(Designator.class))).thenReturn(getQuery);
Mockito.when(getQuery.getResultList()).thenReturn(designatorEntityList);
assertNotNull(designatorDaoImpl.saveDesignators(dto));
}
}
如果你不能改变 DesignatorDaoImpl
然后使用 @RunWith(MockitoJUnitRunner.class)
而不是 MockitoAnnotations.initMocks(this);
as如下:
If you can't change DesignatorDaoImpl
then use @RunWith(MockitoJUnitRunner.class)
instead of MockitoAnnotations.initMocks(this);
as follows:
@Transactional
@Rollback(true)
@RunWith(MockitoJUnitRunner.class)
public class DesignatorDaoImplTest {
@Mock
EntityManager entityManagerMock;
@Mock
TypedQuery<Designator> getQuery;
@InjectMocks
DesignatorDaoImpl designatorDaoImpl;
DesignatorRequestDTO dto = new DesignatorRequestDTO();
List<Designator> designatorEntityList = new ArrayList<>();
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
dto.setLimit(4);
dto.setStart(1);
Designator entity = new Designator();
entity.setId("dgbkk");
designatorEntityList.add(entity);
}
@Test
public void saveDesignatorTest() throws Exception {
Mockito.when(entityManagerMock.createNamedQuery(ArgumentMatchers.anyString(), ArgumentMatchers.eq(Designator.class))).thenReturn(getQuery);
Mockito.when(getQuery.getResultList()).thenReturn(designatorEntityList);
assertNotNull(designatorDaoImpl.saveDesignators(dto));
}
}
相关文章