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

Spring Batch测试报错:找不到javax.sql.DataSource类型合格Bean

解决Spring Batch单元测试中DataSource缺失的问题

在对Spring Batch步骤做单元测试时,触发报错:

spring-boot-batch-test: No qualifying bean of type 'javax.sql.DataSource' available: expected at least 1 bean which qualifies as autowire candidate

问题根源

  1. @EnableBatchProcessing默认会启用依赖数据库的JobRepository组件,即使你的任务逻辑没用到数据库,Spring Batch核心元数据(任务执行记录等)默认需要数据库存储
  2. @SpringBatchTest注解会自动初始化JobRepositoryTestUtils,这个工具类必须依赖DataSource才能创建,上下文无数据源时就会抛出上述错误
  3. 测试类同时使用@DataJpaTest和@SpringBatchTest,两个注解的上下文切片逻辑可能冲突,导致自动配置的嵌入式数据源未生效

错误栈详情:

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'jobRepositoryTestUtils': Unsatisfied dependency expressed through method 'setDataSource' parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'javax.sql.DataSource' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.resolveMethodArguments(AutowiredAnnotationBeanPostProcessor.java:767) ~[spring-beans-5.3.22.jar:5.3.22]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:719) ~[spring-beans-5.3.22.jar:5.3.22]
...(省略后续栈信息)


解决方案

方案1:添加嵌入式内存数据库(快速解决)

这是最简便的方式,Spring Boot会自动配置嵌入式数据源,满足Spring Batch元数据存储需求:

  1. 引入H2嵌入式数据库依赖:
    Maven:
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>test</scope>
    </dependency>
    
    Gradle:
    testImplementation 'com.h2database:h2'
    
  2. 调整测试类注解,移除不必要的@DataJpaTest(若测试不需要JPA切片功能),避免注解冲突:
    @SpringBatchTest
    @ContextConfiguration(classes = { Scheduler.class })
    @TestPropertySource("classpath:calculator-test.properties")
    @RunWith(SpringRunner.class)
    public class CalculatorTest {
        @Autowired private JobLauncherTestUtils jobLauncherTestUtils;
        // 若不需要操作JobRepository元数据,直接移除以下注入
        // @Autowired private JobRepositoryTestUtils jobRepositoryTestUtils;
    
        @Test
        public void test_end_to_end() throws Exception {
                final JobExecution jobExecution = jobLauncherTestUtils.launchJob();
                Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus());
        }
    }
    

方案2:配置内存型JobRepository(彻底摆脱数据库依赖)

如果测试完全不需要持久化Batch元数据,可以配置基于内存的JobRepository,彻底移除数据源依赖:

  1. 创建测试专用配置类,替换默认的JobRepository组件:
    @Configuration
    public class TestBatchConfig {
        @Bean
        public JobRepository jobRepository() throws Exception {
            MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean();
            factory.setTransactionManager(new ResourcelessTransactionManager());
            return factory.getObject();
        }
    
        @Bean
        public JobLauncher jobLauncher(JobRepository jobRepository) {
            SimpleJobLauncher launcher = new SimpleJobLauncher();
            launcher.setJobRepository(jobRepository);
            return launcher;
        }
    
        @Bean
        public JobBuilderFactory jobBuilderFactory(JobRepository jobRepository) {
            return new JobBuilderFactory(jobRepository);
        }
    
        @Bean
        public StepBuilderFactory stepBuilderFactory(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
            return new StepBuilderFactory(jobRepository, transactionManager);
        }
    
        @Bean
        public PlatformTransactionManager transactionManager() {
            return new ResourcelessTransactionManager();
        }
    }
    
  2. 修改测试类,引入该测试配置:
    @SpringBatchTest
    @ContextConfiguration(classes = { Scheduler.class, TestBatchConfig.class })
    @TestPropertySource("classpath:calculator-test.properties")
    @RunWith(SpringRunner.class)
    public class CalculatorTest {
        @Autowired private JobLauncherTestUtils jobLauncherTestUtils;
    
        @Test
        public void test_end_to_end() throws Exception {
                final JobExecution jobExecution = jobLauncherTestUtils.launchJob();
                Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus());
        }
    }
    
    注意:此方案下JobRepositoryTestUtils依然需要数据源,若必须使用该工具类,建议改用方案1。

方案3:移除不必要的测试组件依赖

如果仅需验证Job执行结果,不需要操作JobRepository元数据,可直接移除JobRepositoryTestUtils的注入,减少不必要的依赖:

@SpringBatchTest
@ContextConfiguration(classes = { Scheduler.class })
@TestPropertySource("classpath:calculator-test.properties")
@RunWith(SpringRunner.class)
public class CalculatorTest {
    @Autowired private JobLauncherTestUtils jobLauncherTestUtils;

    @Test
    public void test_end_to_end() throws Exception {
            final JobExecution jobExecution = jobLauncherTestUtils.launchJob();
            Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus());
    }
}

此方案建议配合方案1使用,避免@SpringBatchTest自动初始化JobRepositoryTestUtils时再次触发报错。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 17:32:17