PrepitStatementCallback coverage的Junit测试用例

时间:2017-12-05 09:59:51

标签: java unit-testing junit mockito

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

我正在为我的项目使用Spring框架,我已经为上面的代码编写了Junit测试用例。但我无法涵盖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 个答案:

答案 0 :(得分:0)

该方法正在做很多事情,使其易于检测。

1)我会将新的PreparedStatementCallback移到专门的班级:

public class MyPreparedStatementCallback implements PreparedStatementCallback<Boolean>{

  @Override
  public Boolean doInPreparedStatement(PreparedStatement pst) {
    ....
}

我会在这里测试分离中的doInPreparedStatement方法。它根本不应与之前的测试有关。

2)在原始方法中使用新类并测试是否已通过正确的实例(您需要Mockito here):

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

底线是您不应该使用原始测试方法测试该回调的实现。这太过分了,你的测试将是粗糙的,难以维持。