1

I am trying to test my class that uses a createNativeQuery to query a database

Here is the class that i am using to query the database.

@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;
...
}

I have written a junit test class like below. I have mocked the EntityManager and the Query classes. I am expecting the List<Object[]> from the getResponse() method to be returned when the getResultList method is encountered.

 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;
     }
 
 }

My application.properties goes like this. I am actually using a h2 database.

 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

When I run the test case I am expecting a successful result. But i am getting the below result. This is the table i am trying to access

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
lr-pal
  • 339
  • 2
  • 6
  • 20
  • 1. Your mocks are ignored by SpringBootTest. 2 Show us QueryAdapter, specifically how entity manager is initalized. – Lesiak Feb 26 '21 at 20:36

1 Answers1

0

You have to inject your mocks to class you're trying to test.

Instead of

 @Autowired
 public QueryAdapter dqa;

Try this :

 @InjectMocks
 public QueryAdapter dqa;

Please refer this article to know more : https://howtodoinjava.com/mockito/mockito-mock-injectmocks/

Deepanshu Rathi
  • 381
  • 1
  • 10
  • After i change that to ___ @InjectMocks public QueryAdapter dqa;___ I am getting a null pointer exception in the step____ Query q = entityManager.createNativeQuery("select name from MY_TABLE where id=:id");__________ q is actually null – lr-pal Feb 26 '21 at 15:13
  • Can you try using `@RunWith(MockitoJunitRunner.class)` or If you don't want to change the runner, try using `@MockBean` instead of `@Mock` in your original implementation (Using `@Autowired`) Refer : https://stackoverflow.com/questions/49635396/runwithspringrunner-class-vs-runwithmockitojunitrunner-class/49647467 – Deepanshu Rathi Feb 27 '21 at 07:26