@Transactional
public Boolean save(final StudentLogEntry studentLogEntry) throws SQLException,DaoException{
boolean returnFlag = true;
String sqlInsert = "insert into STUDENT_DETAILS (INSERT_DATE,STUDENT_NAME,STUDENT_ID) values(SYSDATE,?,?)";
returnFlag = jdbcTemplate.execute(
sqlInsert,
new PreparedStatementCallback<Boolean>() {
Boolean b=false;
@Override
public Boolean doInPreparedStatement(PreparedStatement pst) {
try {
pst.setString(2, studentLogEntry.getStuName());
pst.setString(3, studentLogEntry.getStuId());
b=pst.execute();
} catch (SQLException e) {
clicklogger.info("SQLException has occurred while inserting studentlog ",e);
} catch (DataAccessException e) {
clicklogger.info("DataAccessException has occurred while inserting studentlog ",e);
}
return b;
}
}
);
return returnFlag;
}
我正在为项目使用弹簧框架,我为上述代码编写了Junit Test Case。但是我无法覆盖PreparedStatementCallback
。我的测试案例如下:
@Test
public void testSave() throws DaoException, SQLException {
studentDao.setJdbcTemplate(jdbcTemplate);
studentDao.setTransactionManager(transactionManager);
StudentLogEntry studentLogEntry = new StudentLogEntry();
studentLogEntry.getStuName("ABC");
studentLogEntry.getStuId("1234");
assertEquals("true",studentDao.save(studentLogEntry));
}
该方法正在做很多事情以使其容易和清晰可测试。
1)我将新的PreparedStatementCallback
移至专业类:
public class MyPreparedStatementCallback implements PreparedStatementCallback<Boolean>{
@Override
public Boolean doInPreparedStatement(PreparedStatement pst) {
....
}
我将在此处测试doInPreparedStatement
方法。它根本不应该与以前的测试有关。
2)使用原始方法中的新类,并测试是否已通过了适当的实例(您需要在此处使用Mockito):
returnFlag = jdbcTemplate.execute(sqlInsert,new MyPreparedStatementCallback());
和测试:
@InjectMocks
StudentDao studentDao;
@Mock
JdbcTemplate jdbcTemplateMock;
@Captor
ArgumentCaptor argCaptor;
@Before
public void init(){
MockitoAnnotations.initMocks(this);
}
@Test
public void shouldSaveWithCallback(){
// Act
// set up
studentDao.save(studentLogEntry);
myClass.userPressedButton();
Mockito.verify(jdbcTemplateMock).execute(Mockito.anyString(), argCaptor.capture());
// Assert
assertTrue(argCaptor.getValue() instance of MyPreparedStatementCallback);
}
底线是您不应使用原始测试方法测试该回调的实现。这太多了,您的测试将是粗略的,难以维护。