针对多个作业的Spring Batch JUnit测试

ppp*_*van 6 spring spring-batch

我在一个上下文文件中配置了两个作业

<batch:job id="JobA" restartable="true">
        <batch:step id="abc">
            <batch:tasklet >
                <batch:chunk reader="reader" writer="writer" processor="processor"  />
            </batch:tasklet>
      </batch:step>

    </batch:job>

<batch:job id="JobB" restartable="true">
        <batch:step id="abc">
            <batch:tasklet >
                <batch:chunk reader="reader" writer="writer" processor="processor"  />
            </batch:tasklet>
      </batch:step>

    </batch:job>
Run Code Online (Sandbox Code Playgroud)

当我使用JobLauncherTestUtils和测试作业启动对JobA进行单元测试时,它会抛出异常说法

No unique bean of type [org.springframework.batch.core.Job;] is defined: expected single matching bean but found 2: [JobA, JobB]
Run Code Online (Sandbox Code Playgroud)

我尝试使用@Qualifierautowire仍然是相同的事情.我在哪里做错了

编辑

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:META-INF/spring/batch-test-context.xml" })
public class TestJob {

    @Autowired
    private JobExplorer jobExplorer;

    @Autowired
    @Qualifier("JobA")
    private Job JobA;


    @Autowired
    private JobLauncherTestUtils jobLauncherTestUtils;


    @Test
    public void testJob() throws Exception {
        JobParameters jobParameters = getNextJobParameters(getJobParameters());
        assertEquals(BatchStatus.COMPLETED, jobLauncherTestUtils.getJobLauncher().run(JobA, jobParameters));
    }


    private JobParameters getJobParameters() {
        JobParametersBuilder jobParameters = new JobParametersBuilder();
        jobParameters.addString("param", "123");
        return jobParameters.toJobParameters();
    }


    private JobParameters getNextJobParameters(JobParameters jobParameters) {
        String jobIdentifier = jobLauncherTestUtils.getJob().getName();
        List<JobInstance> lastInstances = jobExplorer.getJobInstances(jobIdentifier, 0, 1);
        JobParametersIncrementer incrementer = jobLauncherTestUtils.getJob().getJobParametersIncrementer();
        if (lastInstances.isEmpty()) {
            return incrementer.getNext(jobParameters);
        } else {
            List<JobExecution> lastExecutions = jobExplorer.getJobExecutions(lastInstances.get(0));
            return incrementer.getNext(lastExecutions.get(0).getJobParameters());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

例外是

No unique bean of type [org.springframework.batch.core.Job;] is defined: expected single matching bean but found 2: [JobA, JobB]`
Run Code Online (Sandbox Code Playgroud)

Ily*_*hin 5

也许迟到了,

但我找到了自己的工作解决方案:手动配置JobLauncherTestUtils:

@Inject
@Qualifier(value = "Job1")
private Job job;

@Inject
private JobLauncher jobLauncher;

@Inject
private JobRepository jobRepository;

private JobLauncherTestUtils jobLauncherTestUtils;

private void initailizeJobLauncherTestUtils() {
    this.jobLauncherTestUtils = new JobLauncherTestUtils();
    this.jobLauncherTestUtils.setJobLauncher(jobLauncher);
    this.jobLauncherTestUtils.setJobRepository(jobRepository);
    this.jobLauncherTestUtils.setJob(job);
}

@Before
public void setUp() throws Exception {
    this.initailizeJobLauncherTestUtils();
}
Run Code Online (Sandbox Code Playgroud)

使用它,您可以控制应该应用JobLauncherTestUtils的Job.(默认情况下,它需要在上下文中单个作业配置)

  • 为了他人的利益。使用此方法删除“@SpringBatchTest”注释。提到的注释会自动注入“JobLauncherTestUtils”。 (2认同)

mad*_*fox 5

@Autowired因为setter 上有一个注释,所以JobLauncherTestUtils.setJob(Job job)我必须在创建 bean 后使用 MergedBeanDefinitionPostProcessor 来设置属性:

@Configuration
public class TestBatchConfiguration implements MergedBeanDefinitionPostProcessor {

    @Autowired
    @Qualifier("JobA")
    private Job job;

    @Bean(name="jtestl")
    public JobLauncherTestUtils jobLauncherTestUtils() {
        JobLauncherTestUtils jobLauncherTestUtils = new JobLauncherTestUtils();
        jobLauncherTestUtils.setJob(job);
        return jobLauncherTestUtils;
    }

    /**
     * /sf/ask/1569129831/
     * This is needed to inject the correct job into JobLauncherTestUtils
     */
    @Override
    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        if(beanName.equals("jtestl")) {
            beanDefinition.getPropertyValues().add("job", getMyBeanFirstAImpl());
        }
    }

    private Object getMyBeanFirstAImpl() {
        return job;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}
Run Code Online (Sandbox Code Playgroud)


m.a*_*bin 1

您在 bean 配置文件中声明了两个相似的 bean。要解决上述问题,您需要@Qualifier("JobA")告诉@Qualifier("JobB")Spring 哪个 bean 应该自动连接到哪个作业。

  • Job Bean 在 JobLauncherTestUtils 中自动装配,期望每批只有一个 Bean。 (4认同)