【发布时间】:2017-03-28 09:43:57
【问题描述】:
我想将合适的对象传递给 verify 方法,而不仅仅是 any()。
有办法吗?
我不能只是采用和复制 Lambda 方法并将结果传递给验证。这不起作用,因为无法直接测试 Lambda。
我的单元测试显然还没有接近测试任何东西:
@Test
public void testRunTrigger() {
campaignTrigger.updateCampaignStatus();
verify(jdbcTemplate).update(any(PreparedStatementCreator.class));
assertEquals("UPDATE campaign SET state = 'FINISHED' WHERE state IN ('PAUSED','CREATED','RUNNING') AND campaign_end < ? ", campaignTrigger.UPDATE_CAMPAIGN_SQL);
}
这是我正在测试的课程:
@Component
@Slf4j
public class CampaignTrigger {
final String UPDATE_CAMPAIGN_SQL = String.format("UPDATE campaign SET state = '%s' " +
" WHERE state IN (%s) AND campaign_end < ? ", FINISHED,
Stream.of(PAUSED, CREATED, RUNNING)
.map(CampaignState::name)
.collect(Collectors.joining("','", "'", "'")));
@Autowired
private JdbcTemplate jdbcTemplate;
@Scheduled(cron = "${lotto.triggers.campaign}")
@Timed
void updateCampaignStatus() {
jdbcTemplate.update(con -> {
PreparedStatement callableStatement = con.prepareStatement(UPDATE_CAMPAIGN_SQL);
callableStatement.setTimestamp(1, Timestamp.valueOf(LocalDateTime.now()));
log.debug("Updating campaigns statuses.");
return callableStatement;
});
}
任何建议或理论知识,这不是这样做的方法,我将不胜感激。
【问题讨论】:
-
您可以检查
con.prepareStatement(UPDATE_CAMPAIGN_SQL)和callableStatement.setTimestamp(1, Timestamp.valueOf(LocalDateTime.now()))是否使用适当的参数调用... -
您能否提供更多详细信息,我该怎么做?
-
那种取决于
con是否是一个模拟。同时,再次思考,在调用模拟的JdbcTemplate时捕获参数,正如@GhostCat 建议的那样,更加清晰和优雅 -
不,这不是模拟 :( 。是的,这是一个不错的方法,但我得到的只是 CampaignTrigger$$Lambda$6/103536485@1e67a849 对象,似乎无法访问它的内部。
-
你说得对,没什么可看的,因为它是
PreparedStatementCreator接口的实现。分解职责,updateCampaignStatus应该调用jdbcTemplate.update,具体实现为PreparedStatementCreator。如果您有 2 个不同的类,您可以单独检查您的PreparedStatementCreator是否正在生成所需的PreparedStatement以及该特定创建者是否调用了jdbcTemplate。既然都是内联,除了我最初的建议之外,我真的看不出你能做什么(我知道,我改变了两次主意)
标签: java unit-testing junit mocking mockito