我有jdbcTemplate代码,正在尝试在其上编写单元测试用例。
public void updateData(List<Student> students, String status){
try{jdbcTemplate.batchUpdate("update query", new BatchPreparedStatementSetter(){
@Override
public int getBatchSize()
return students.size();
}
@Override
public void setValues(PreparedStatement ps int i){
Student student = students.get(i);
ps.setInt(1, student.getRollNo());
ps.setString(2, student.getName());
}
});
}catch(Exception ex){}
}
但是问题是我无法覆盖完整的代码。我可以讲到:
try {jdbcTemplate.batchUpdate(“更新查询”,新 BatchPreparedStatementSetter(){
测试代码段
@Test
public void testMe(){
List<Student> students = new ArrayList<>();
mockedObject.updateData(students ,"success");
}
请帮助。
答案 0 :(得分:2)
困难之处在于,包含要测试的主要逻辑的new BatchPreparedStatementSetter(){ ...}
实例是updateData()
方法的实现细节。它仅在测试的方法内定义。
要解决您有两种经典方法:
@DataJpaTest
支持测试切片(这最终是部分集成测试),这会更加简单,因为您将能够测试副作用,并且在声明数据库中的状态而不是在数据库中声明状态时会更有用。您的代码中的语句。BatchPreparedStatementSetter
实例创建。例如:
@Service
class BatchPreparedStatementFactory{
public BatchPreparedStatementSetter ofStudentsBatchPreparedStatementSetter(List<Student> students, String status){
return
new BatchPreparedStatementSetter(){
@Override
public int getBatchSize()
return students.size();
}
@Override
public void setValues(PreparedStatement ps int i){
Student student = students.get(i);
ps.setInt(1, student.getRollNo());
ps.setString(2, student.getName());
}
});
}
}
现在在原始代码中使用它:
// inject it
BatchPreparedStatementFactory batchPreparedStatementFactory;
public void updateData(List<Student> students, String status){
try{jdbcTemplate.batchUpdate("update query", batchPreparedStatementFactory.ofStudentsBatchPreparedStatementSetter(students, status );
}catch(Exception ex){}
}
现在您有两个组成部分,因此有两个测试:
BatchPreparedStatementFactoryTest
(无模拟),用于测试getBatchSize()
和setValues()
。那很直。jdbcTemplate.batchUpdate()
是使用预期参数调用的,尤其是BatchPreparedStatementFactory.ofStudentsBatchPreparedStatementSetter(...)
返回的实例。jdbcTemplate
,BatchPreparedStatementFactory
和BatchPreparedStatementSetter
。例如第二种情况:
// mock the factory return
BatchPreparedStatementSetter batchPreparedStatementSetterDummyMock = Mockito.mock(BatchPreparedStatementSetter.class);
Mockito.when(batchPreparedStatementFactoryMock.ofStudentsBatchPreparedStatementSetter(students, status))
.thenReturn(batchPreparedStatementSetterDummyMock);
// call the method to test
updateData(students, status);
// verify that we call the factory with the expected params
Mockito.verify(jdbcTemplateMock)
.batchUpdate("update query", batchPreparedStatementSetterDummyMock);
就我个人而言,我不喜欢那种带有过于精细的模拟的单元测试。我会坚持使用@DataJpaTest
或更多的全局集成测试来断言与JDBC / JPA有关的事情。