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

Spring Boot集成测试SQL脚本路径错误及测试策略疑问

问题解决与测试优化方案

1. 修复脚本读取错误(CannotReadScriptException)

脚本读取失败是因为@Sql注解的路径格式错误,你用了{/resources/schema.sql}的错误写法,正确路径写法有两种:

  • 直接写"/schema.sql"(Spring默认从类路径根目录查找,resources就是类路径根目录)
  • 显式指定类路径:"classpath:schema.sql"

修改后的测试方法注解:

@Test
@Sql("/schema.sql")
void shouldCreatePost() throws Exception {
    // ... 原有代码
}

另外,无需手动指定@TestExecutionListeners(listeners = { SqlScriptsTestExecutionListener.class }),Spring Boot测试默认已包含该监听器,可以直接删除这个注解。

2. 切换到内存数据库(符合集成测试隔离要求)

你计划用内存数据库做测试,但当前配置的是本地真实MySQL,集成测试应使用内存数据库避免依赖外部环境,推荐用H2:

  • 添加H2测试依赖(Maven):
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>test</scope>
</dependency>
  • 在src/test/resources下创建测试专用配置文件application-test.properties:
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.defer-datasource-initialization=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
spring.sql.init.mode=always
  • 在测试类上添加@ActiveProfiles("test")启用测试配置:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@ActiveProfiles("test")
class OrderServiceApplicationTests {
    // ... 原有代码
}

3. 修复原生SQL查询的兼容性问题

MySQL不支持FULL JOIN(FULL OUTER JOIN),你的Repository查询中使用该语法会导致执行错误。如果需要全连接逻辑,需用LEFT JOIN + UNION + RIGHT JOIN模拟:

@Query(
    value = "SELECT order_id,title,description,requirement,salary,user_info.name,user_info.contact,date"+
            " FROM job_order " +
            " LEFT JOIN user_info " +
            " ON sender_id=user_info.id" +
            " WHERE order_id= ?1 " +
            " UNION " +
            " SELECT order_id,title,description,requirement,salary,user_info.name,user_info.contact,date"+
            " FROM job_order " +
            " RIGHT JOIN user_info " +
            " ON sender_id=user_info.id" +
            " WHERE order_id= ?1 ;",
    nativeQuery = true
)
Response singlejob(int order_id);

如果业务只需要关联存在的sender_id对应的user_info,换成LEFT JOIN或INNER JOIN更合理。

4. 优化测试逻辑

当前测试先调用jobRepository.save再POST同一个Job,不符合接口创建数据的业务逻辑,建议调整为:

@Test
@Sql("/schema.sql") // 初始化user_info数据
void shouldCreatePost() throws Exception {
    // 构造未指定order_id的Job(order_id建议由数据库自动生成)
    JobOrder job = new JobOrder();
    job.setTitle("Hiring software engineer");
    job.setDescription("responsible for developing and maintaining mobile app");
    job.setRequirement("Need to know basic sql springboot,2 years exp");
    job.setSalary(234);
    job.setSender_id(1); // 关联schema.sql中插入的user_info的id

    String request = objectMapper.writeValueAsString(job);

    mockMvc.perform(MockMvcRequestBuilders.post("/Job/Joborder")
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(request))
            .andExpect(status().is2xxSuccessful());

    // 验证数据库中存在该Job
    Optional<JobOrder> savedJob = jobRepository.findById(1);
    assertThat(savedJob).isPresent();
    assertThat(savedJob.get().getTitle()).isEqualTo("Hiring software engineer");
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 00:45:34