You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot集成测试中如何断言数据库状态?是否仅能使用JdbcTemplate?

Spring Boot集成测试中检查数据库状态的几种方案

你提到的场景里,注入JdbcTemplate并不是唯一方案,下面是几种无需新增业务Repository、不侵入业务代码的实现方式:

一、JdbcTemplate:直接执行SQL查询

这是最通用的方案,不管项目用JDBC还是JPA都能直接用,完全独立于业务代码。

只需要在测试类中注入JdbcTemplate,然后编写查询SQL断言数据库状态:

// 在测试类中添加注入
@Autowired
JdbcTemplate jdbcTemplate;

@Test
@Sql(statements = "TRUNCATE \"user\" CASCADE;")
@Sql(statements = """
        INSERT INTO "user" (id, name) VALUES (15, 'Sasha');
        INSERT INTO "user" (id, name) VALUES (16, 'Alex');
        INSERT INTO account (id, user_id, balance) VALUES (1, 15, 10);
        INSERT INTO account (id, user_id, balance) VALUES (2, 16, 0);
        """)
void performTransfer_ifUserHasSufficientBalance_recipientHasAccount_returns200() throws Exception {
    TransferRequestDto transferDto = new TransferRequestDto();
    transferDto.setRecipientId(16L);
    transferDto.setAmount(BigDecimal.valueOf(10L));

    mockMvc.perform(patch("/api/money-transfer")
                    .with(jwt().jwt(jwt -> jwt
                            .claim("userid", 15L)))
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(objectMapper.writeValueAsString(transferDto)))
            .andExpect(status().isOk());

    // 断言数据库状态
    BigDecimal sashaBalance = jdbcTemplate.queryForObject(
        "SELECT balance FROM account WHERE user_id = ?",
        BigDecimal.class,
        15L
    );
    BigDecimal alexBalance = jdbcTemplate.queryForObject(
        "SELECT balance FROM account WHERE user_id = ?",
        BigDecimal.class,
        16L
    );

    Assertions.assertEquals(BigDecimal.ZERO, sashaBalance);
    Assertions.assertEquals(new BigDecimal("10"), alexBalance);
}

二、TestEntityManager:JPA项目专属工具

如果你的项目用了JPA,可以用TestEntityManager来执行查询,不需要依赖业务Repository。它支持JPQL和原生SQL,还能帮你刷新持久化上下文,确保查询到最新的数据库状态:

// 在测试类中添加注入
@Autowired
TestEntityManager entityManager;

// 测试方法中添加断言
mockMvc.perform(...)
       .andExpect(status().isOk());

// 刷新并清空持久化上下文,避免缓存干扰
entityManager.flush();
entityManager.clear();

// 用原生SQL查询
BigDecimal alexBalance = entityManager.createNativeQuery(
    "SELECT balance FROM account WHERE user_id = :userId",
    BigDecimal.class
).setParameter("userId", 16L)
.getSingleResult();

Assertions.assertEquals(new BigDecimal("10"), alexBalance);

三、JdbcTestUtils:简化数据库操作的工具类

Spring Test提供的JdbcTestUtils封装了常用的数据库操作,比如统计行数、查询单个值,能让测试代码更简洁:

// 在测试类中注入JdbcTemplate后使用
mockMvc.perform(...)
       .andExpect(status().isOk());

// 查询单个值
BigDecimal sashaBalance = JdbcTestUtils.queryForObject(
    jdbcTemplate,
    "SELECT balance FROM account WHERE user_id = ?",
    BigDecimal.class,
    15L
);

// 统计符合条件的行数(验证转账后账户余额为0)
int zeroBalanceCount = JdbcTestUtils.countRowsInTableWhere(
    jdbcTemplate,
    "account",
    "user_id = ? AND balance = 0",
    15L
);

Assertions.assertEquals(BigDecimal.ZERO, sashaBalance);
Assertions.assertEquals(1, zeroBalanceCount);

核心思路总结

这些方案的共同点是:只在测试代码中直接操作数据库,完全不修改业务代码,避免了为测试新增查询方法的不合理性。你可以根据项目的技术栈(纯JDBC/JPA)选择最适合的方式。

内容的提问来源于stack exchange,提问作者Sergey Zolotarev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 22:53:12