0

I am using Mockito for testing my java classes using Junit. I am new to the Mockito and Junit test cases. I have one class which is having spring configuration. Please see the code snippet below.

 public abstract class AbstractTaskDao implements TaskDao {
        @Autowired
        NamedParameterJdbcTemplate jdbcTemplate;

        @Override
        public void addTask(BlockingQueue<String> queue, LocalDate tdate) {
            String sql = getQuery();
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("tdate", Date.valueOf(tdate));


            ((JdbcTemplate) jdbcTemplate.getJdbcOperations()).setFetchSize(1000);
            jdbcTemplate.query(sql, paramMap,new classA());
        }
        protected abstract String getQuery();
    }

    Below is my test class.

    public class AbstractTaskDaoTest { 
        @Mock NamedParameterJdbcTemplate jdbcTemplate; 
        @Mock JdbcOperations operation;
        BlockingQueue<String> myqueue;
        @Before
         public void setUp() throws IOException {   
           jdbcTemplate=mock(NamedParameterJdbcTemplate.class);         
                when(jdbcTemplate.getJdbcOperations()).thenReturn(operation);       
              //use reflection to inject autowired field.       
       org.springframework.test.util.ReflectionTestUtils.setField(abstratTaskPDao, "jdbcTemplate", jdbcTemplate);

                        }

                    @Test
                    public void testTask() throws InterruptedException{
                        LocalDate tdate=LocalDate.parse("2014-02-23");
                        AbstractTaskDao  abstratTaskDao = Mockito.mock(AbstractTaskDao .class, Mockito.CALLS_REAL_METHODS);
                        System.out.println("\n\t sql-"+abstratTaskDao.getQuery());
                        abstratTaskDao.addTask(myqueue,tdate);
                    }
                }

The above test cases throws NullPointerException at line "((JdbcTemplate) jdbcTemplate.getJdbcOperations()).setFetchSize(1000);"

So in above code I am getting getQuery as null. as its implemented by other classes like class MyclassQuery extends AbstractTaskDao contains implementation of the method getQuery(). But I am new to the world of Mockito and Junit test cases so I am not getting how to give explicit call in testing.

2nd thing is the @Autowired fields here it is jdbcTemplate is getting null.So how will I get the value of this.

Update: I am getting class cast exception for code "((JdbcTemplate) jdbcTemplate.getJdbcOperations()).setFetchSize(1000);" As jdbcTemplate is NamedParameterJdbcTemplate. How to resolve this.

To solve this issue I added below line to code in AbstractTaskDaoTest class.
 @Mock JdbcTemplate jdbcTemp;
 jdbcTemp=mock(JdbcTemplate.class);         
 when(jdbcTemplate.getJdbcOperations()).thenReturn(jdbcTemp);     
Kamini
  • 690
  • 2
  • 13
  • 36
  • 1) Mock the `jdbcTemplate` 2) use @injectMocks annotation to inject your dependencies. These 2 things are common practice with mokito. – Minh Kieu Jun 26 '17 at 09:44
  • The combination of mocking an abstract method and specifying the flag `Mockito.CALLS_REAL_METHODS` should not work I guess. You might want to mock the method or create a Mock for one of the subclasses that are implementing the method. – Florian S. Jun 26 '17 at 09:45
  • @MinhKieu I added @ InjectMocks NamedParameterJdbcTemplate jdbcTemplate; like this but still it is giving null value. And even if I get value of this template here how I will pass this value to the class I want to test? – Kamini Jun 26 '17 at 09:56
  • Sorry for not being clearer. I am assume you know what I talking about :). Ok so you @Mock the `NamedParameterJdbcTemplate jdbcTemplate`. Obviously this is just a mock so you need to tell Mockito how you want it to work. For example `JdbcOperations operation = Mock(JdbcOperations.class);when(jdbcTemplate.getJdbcOperations()).thenReturn(operation);`. Hopes this make it clearer. – Minh Kieu Jun 26 '17 at 10:06
  • @MinhKieu thanks for making it clearer, when I tried to add this line jdbcTemplate.getJdbcOperations() as the jdbcTemplate giving null object so it gives nullpointer when I try to set the operations in its null object. – Kamini Jun 26 '17 at 10:15
  • @MinhKieu I mocked the jdbctemplate my error now is at line when(abstratTaskDao.jdbcTemplate).thenReturn(jdbcTemplate); as WrongTypeOfReturnValue: – Kamini Jun 26 '17 at 10:21

1 Answers1

0

Try this code, I have not compile fully so you will need to figure out the last line.

@Test
public void testTask() throws InterruptedException {
    //arrange
    LocalDate tdate = LocalDate.parse("2014-02-23");
    AbstractTaskDao abstratTaskDao = Mockito.mock(AbstractTaskDao.class, Mockito.CALLS_REAL_METHODS);
    NamedParameterJdbcTemplate jdbcTemplate = Mockito.mock(NamedParameterJdbcTemplate.class);
    JdbcOperations operations =  Mockito.mock(JdbcOperations.class);

    when(jdbcTemplate.getJdbcOperations()).thenReturn(operations);
    when(abstratTaskDao.getQuery()).thenReturn("select * from dual");

    //use reflection to inject autowired field.
    org.springframework.test.util.ReflectionTestUtils.setField(abstratTaskDao, "jdbcTemplate", jdbcTemplate);

    System.out.println("\n\t sql-"+abstratTaskDao.getQuery());

    //act
    abstratTaskDao.addTask(myqueue, tdate);

    //assert
    verify(jdbcTemplate).query(...);

}
Minh Kieu
  • 475
  • 3
  • 9
  • I am getting this error"Wanted but not invoked: Actually, there were zero interactions with this mock." at line verify().queryForList() – Kamini Jun 27 '17 at 09:35
  • update your question and post your new test code. Basically, it is saying that you verify some method call to execute once but its never called. – Minh Kieu Jun 27 '17 at 11:50
  • I have updated it, the issue is now giving as Class cast exception for (JdbcTemplate). as I am passing NamedJdbcparameterTemplate object. – Kamini Jun 28 '17 at 07:29
  • Error :org.springframework.jdbc.core.JdbcOperations$$EnhancerByMockitoWithCGLIB$$ba144ce6 cannot be cast to org.springframework.jdbc.core.JdbcTemplate – Kamini Jun 28 '17 at 07:42
  • `jdbcTemplate.getJdbcOperations()` returns JdbcOperations based on the documentation. So I guess your casting to the wrong type? – Minh Kieu Jun 28 '17 at 08:10
  • I was able to resolve the above issue, I have updated with answer. – Kamini Jun 29 '17 at 16:04