Spring-batch 正在测试上下文中寻找数据源,即使我在测试上下文和应用程序上下文中都没有使用任何数据库连接。
引起:org.springframework.beans.factory.UnsatisfiedDependencyException:创建名称为“jobRepositoryTestUtils”的bean时出错:通过方法“setDataSource”参数0表示不满足的依赖关系;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:没有可用的“javax.sql.DataSource”类型的合格 bean:预计至少有 1 个符合自动装配候选资格的 bean。依赖注释:{} 在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.resolveMethodArguments(AutowiredAnnotationBeanPostProcessor.java:767) ~[spring-beans-5.3.22.jar:5.3.22] 在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:719) ~[spring-beans-5.3.22.jar:5.3.22] 在 org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119) ~[spring-beans-5.3.22.jar:5.3.22] 在org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)〜[spring-beans-5.3.22.jar:5.3.22] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1431) ~[spring-beans-5.3.22.jar:5.3.22] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:619) ~[spring-beans-5.3.22.jar:5.3.22] 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.22.jar:5.3.22] 在 org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.22.jar:5.3.22] 在 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.22.jar:5.3.22] 在 org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.22.jar:5.3.22] 在 org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.22.jar:5.3.22] 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955) ~[spring-beans-5.3.22.jar:5.3.22] 在 org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.22.jar:5.3.22] 在 org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.22.jar:5.3.22] 在 org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:127) ~[spring-test-5.3.22.jar:5.3.22] 在 org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60) ~[spring-test-5.3.22.jar:5.3.22] 在 org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:276) ~[spring-test-5.3.22.jar:5.3.22] 在 org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:244) ~[spring-test-5.3.22.jar:5.3.22] 在 org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99) ~[spring-test-5.3.22.jar:5.3.22] 在 org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124) ~[spring-test-5.3.22.jar:5.3.22] ... 71 更多
测试班:
import org.junit.runner.RunWith;
import org.springframework.batch.test.context.SpringBatchTest;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
@SpringBatchTest
@ContextConfiguration(classes = { Scheduler.class })
@ComponentScan
@DataJpaTest
@TestPropertySource("classpath:calculator-test.properties")
public class CalculatorTest {
@Autowired private JobLauncherTestUtils jobLauncherTestUtils;
@Autowired private JobRepositoryTestUtils jobRepositoryTestUtils;
@Test
public void test_end_to_end() throws Exception {
final JobExecution jobExecution = jobLauncherTestUtils.launchJob();
Assert.assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus());
}
}
配置类:
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableBatchProcessing
class Scheduler {
@Autowired private JobBuilderFactory jbf;
@Autowired private StepBuilderFactory sbf;
@Bean Tasklet tasklet1() { return new TaskletCalculateDivision(); }
@Bean Tasklet tasklet2() { return new TaskletCalculateAddition(); }
@Bean Step step1() { return sbf.get("Division").tasklet(tasklet1()).build(); }
@Bean Step step2() { return sbf.get("Addition").tasklet(tasklet2()).build(); }
@Bean Job job() { return jbf.get("Calculate").start(step1()).next(step2()).build(); }
}
我尝试在 spring-batch 步骤上应用单元测试。
我没有找到更好的解决方案。我解决了这个问题:
@Bean DataSource getDataSource() { return DataSourceBuilder.create().driverClassName("org.h2.Driver").url("jdbc:h2:mem:AZ;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE").username("user1").password("pass").build(); }
如果您想在测试中使用
@SpringBatchTest
注释,您的类路径中必须有一个数据源 bean。这是因为 Spring Batch 设计的一部分有一些表将存储批处理执行信息。这是 spring-batch 本身构建的。
请阅读 Spring Batch 文档
从 JobRepository 部分下:
除了 dataSource 和 transactionManager 之外,前面列出的配置选项都不是必需的。