0

I have DAO class as below:-

// Here I have a class that creates it's own jdbcTemplate using new // jdbcTemplate(dataSource)

@Repository
public class MyDao {
  @Autowired
  @Qualifier("db2JdbcTemplate)"
  JdbcTemplate jdbcTemplateDB2;
  public int insertTable(Company comp) {
    int ret = 0;
    try {
      ret = this.jdbcTemplateDB2(db2DataSource).update(ïnsert into "+ table_name + "(COL1,COL2,...) values (?,?,?,..)",
           ps-> {
               ps.setString(1, comp.getName);
               .......
             });
      return ret;
    } catch (Exception ex) {
        // log etc
    }
  }
}

My Test class is as below:-

    @RunWith(MockitoJUnitRunner.class)
    public class MyTest {
    
      @Mock 
      JdbcTemplate jdbcTemplateDB2;
    
      Company comp = new Company(); // this is followed by setter fn to set values.
    
      MyDao mydao = Mockito.mock(MyDao.class);
      Mockito.when(((jdbcTemplateDB2.update(any(String.class), 
                                     any(PreparedStatement.class))).thenReturn(2);
      ReflectionUtils.setField(mydao, "jdbcTemplateDB2", jdbcTemplateDB2);
    
      int bVal = mydao.insertTable(cmp);
    
    }
}

iVal is not getting value 2. It is making original update call and returning value like 0/1. Getting UnnecessaryStubbingException. If I make lenient() call the exception goes away but result is same (expected as lenient only removes warning). How to make this stubbing work?

Ranajit
  • 21
  • 1
  • 5

1 Answers1

0

In this line: MyDao mydao = Mockito.mock(MyDao.class); you're creating a mock object, which overrides your actual class'x behavior, but you seem to want to test this very class, so it doesn't make any sense. What you need to do is: create an actual instance of the class and inject mocks into it (you're using ReflectionUtils to do that, but Mockito has it's own, simple mechanism to do that).

@Mock 
JdbcTemplate jdbcTemplateDB2;
// this tells mockito to create the object and inject mocks into it
@InjectMocks
MyDao myDao;

@Test
void test() {
    // define the behavior for the mock
    when(jdbcTemplateDB2.update(...)).thenReturn(2);

    // call the actual method of the tested class object (not a mock)
    int result = myDao.insertTable(...);

    // perform assertions (e.g. verify the result value)
}

Recommended reading: Mockito documentation (very comprehensive, yet simple).

Important note: field injection is discouraged.

Jonasz
  • 1,617
  • 1
  • 13
  • 19
  • I have used ind always getting NullPointerException. – Ranajit Sep 13 '22 at 11:35
  • NPE was due to internal object. I again set it using ReflectionUtil. Need to check how to avoid it. – Ranajit Sep 19 '22 at 11:43
  • I just ran it using simple query. But unable to use the above code. how to mock the whole update as below? update(ïnsert into "+ table_name + "(COL1,COL2,...) values (?,?,?,..)", ps-> { ps.setString(1, comp.getName); ....... }); This is getting out of hand. Any pointer? – Ranajit Sep 19 '22 at 11:47
  • specially as second parameter is PreparedStatementCallback – Ranajit Sep 19 '22 at 11:49
  • Can anyone please point me to a JUnit test code that test properly jdbc execute/update calls with PreparedStatementCallback ? That will be really great help. – Ranajit Sep 19 '22 at 12:40