java - 如何对我收到正确的 PreparedStatement 进行单元测试?

标签 java unit-testing junit mocking mockito

我想将合适的对象传递给验证方法,而不仅仅是 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);
}

这是我正在测试的类(class):

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

任何建议或理论知识表明这不是这样做的方法,我将不胜感激。

最佳答案

您不应该模拟您无法控制的代码。仅模拟您对其​​进行测试的代码,因为在模拟时您假设您知道(即您定义)模拟类的工作方式。

在这里,你不知道 jdbcTemplate 是如何工作的,也不知道用一些 lambda 调用它是否真的如你所想的那样。

使用您无法控制的代码来测试您的代码是集成测试的重点。 IE。您应该将您的 CampaignTrigger 与真实数据库(或内存中的数据库)一起测试,并且不要模拟 jdbcTemplate

关于java - 如何对我收到正确的 PreparedStatement 进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43066105/

相关文章:

java - 反序列化 Gson 中的通用列表

java - 如何为具有 topComponents 成员变量的类编写 junit 测试?

java - Spring Formatting SPI 是否需要使用 JSP 标签或什么?

java - 自定义Jtable滚动条

java - 在 Java 中舍入负数

Python 单元测试条件断言

unit-testing - Jest – 如何模拟模块中的非默认导出?

java - 在 Spring 中模拟用户

intellij-idea - IntelliJ 滚动控制台在测试执行后结束

java - 如何使用 NoSuchAlgorithmException 和 KeyStoreException 覆盖 JUnit 的 block 捕获