[英]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.