[英]How to validate PreparedStatement scenario with Mockito. Unable to mock the PreparedStatement class in test class
我试图在测试 class 中模拟 PreparedStatement class。 我是这个单元测试用例实现的新手。 有人可以指导我如何验证这种情况。
下面的代码是表单服务 impl class。
String sqlToUpdateDeploymentTable = UPDATE_DEPLOYMENT_BY_REQUEST_ID_FOR_APPROVE_AND_REJECT;
getJdbcTemplate().update(sqlToUpdateDeploymentTable, request.getApprover(), request.getApproverComment(),
request.isApproved() ? APPROVED : REJECTED, Timestamp.from(Instant.now()), request.getRequestId());
String sqlToUpdateDeploymentAprrovalTable = INSERT_RECORD_INTO_DEPLOYMENT_APPROVAL;
getJdbcTemplate().update(new PreparedStatementCreator() {
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
PreparedStatement ps = connection.prepareStatement(sqlToUpdateDeploymentAprrovalTable);
ps.setString(1, request.getApprover());
ps.setString(2, request.getRequestId());
return ps;
}
});
if (request.isApproved()) {
return DEPLOYEMNET_REQUEST + AppConstants.REQ_PREFIX + request.getRequestId() + HAS_BEEN_APPROVED;
}
下面的代码来自测试 class。 @Mock JdbcTemplate jdbcTemplate;
@Mock
Connection connection;
@Mock
PreparedStatementCreator statementcreator;
@Mock
PreparedStatement statement;
sql = "Some Sql query"
RequestDto requestDto = new RequestDto();
requestDto.setRequestId("123445");
String APPROVED = "approved";
String query = "UPDATE db.code SET approval_time="
+ Timestamp.from(Instant.now()) + " WHERE request_id=" + requestDto.getRequestId();
Mockito.when(jdbcTemplate.update(new PreparedStatementCreator() {
statement.createPreparedStatement(Connection connection) throws SQLException {
PreparedStatement ps = connection.prepareStatement(query);
ps.setString(2, requestDto.getRequestId());
return ps;
}
})).thenReturn(1);
Mockito.when(jdbcTemplate.update(query,Timestamp.from(Instant.now()), requestDto.getRequestId())).thenReturn(0);
//Mockito.when(PreparedStatement(statement).createPreparedStatement(connection)).thenReturn(statement);
String response = utilimpl.approverReject(requestDto, errors);
System.out.println(response);
在测试 class 中,我无法进入 PreparedStatementCreator 块。 我在测试 class 中模拟了所有必需的 class。 我不确定我在哪里失踪。
在 ArgumentCaptor 的帮助下,我设法测试了 PreparedStatementCreator。 这样我们发送给查询方法的arguments就被捕获了。 随后,执行覆盖的方法,我验证结果是否符合我们的预期。
@ExtendWith(MockitoExtension.class)
class PostgresJdbcAdapterTest {
private PostgreJdbcRepository repository;
@Mock
private JdbcTemplate template;
@Mock
private DataSource dataSource;
@Mock
private Connection conn;
@Mock
private PreparedStatement stmt;
@BeforeEach
void init() {
repository = new PostgresJdbcAdapter(dataSource);
ReflectionTestUtils.setField(repository, "template", template);
}
@Test
void when_customReportQuery_then_result() throws SQLException {
ArgumentCaptor<PreparedStatementCreator> creatorCaptor = ArgumentCaptor.forClass(PreparedStatementCreator.class);
ArgumentCaptor<ReportRowCallbackHandler> handlerCaptor = ArgumentCaptor.forClass(ReportRowCallbackHandler.class);
repository.customReportQuery(request);
BDDMockito.given(conn.prepareStatement(anyString())).willReturn(stmt);
verify(template).query(creatorCaptor.capture(), handlerCaptor.capture());
PreparedStatementCreator creator = creatorCaptor.getValue();
creator.createPreparedStatement(conn);
verify(stmt).setString(1, request.getParam());
ReportRowCallbackHandler handler = handlerCaptor.getValue();
ResultSet rs = mock(ResultSet.class);
handler.processRow(rs);
Assertions.assertThat(repository.customReportQuery(request)).isEmpty();
}
}
class PostgresJdbcAdapter
@Repository
public class PostgresJdbcAdapter extends JdbcDaoSupport implements ReportPostgreJdbcRepository {
private static final String RESULT_MESSAGE = "JDBC - POSTGRES - Query: with {} records";
private static final String EXCEPTION_MESSAGE = "JDBC - POSTGRES - Error trying to execute query: {}";
private final JdbcTemplate template;
@Autowired
public PostgresJdbcAdapter(DataSource dataSource) {
this.template = new JdbcTemplate(dataSource);
setDataSource(dataSource);
}
@Override
public List<ReportRow> customReportQuery(ReportRequest request) {
String sql = "SELECT * FROM table WHERE table.name = ?";
PreparedStatementCreator creator = conn -> {
PreparedStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, request.getName());
return stmt;
};
try {
ReportRowCallbackHandler handler = new ReportRowCallbackHandler();
template.query(creator, handler);
log.info(RESULT_MESSAGE, handler.getResult().size());
return handler.getResult();
} catch (DataAccessException ex) {
log.error(EXCEPTION_MESSAGE, ex.getMessage());
throw new PostgreJdbcException(ex);
}
}
}
和行处理程序
public class ReportRowCallbackHandler implements RowCallbackHandler {
private final List<ReportRow> result = new LinkedList<>();
@Override
public void processRow(ResultSet rs) throws SQLException {
ReportRow row = ReportRow.builder()
.name(rs.getString("name"))
.build();
result.add(row);
}
public List<ReportRow> getResult() {
return Collections.unmodifiableList(result);
}
}
我希望它对每个人都有帮助。 此致
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.