首页 > 解决方案 > Spring Batch:为什么单元测试会运行该步骤两次?

问题描述

我正在学习对 Spring Batch 进行单元测试,但我正在努力调试单元测试两次执行相同的 Spring Batch 作业的情况。

由于这是我在 Spring Batch 中的第一个单元测试,我试图找到一些其他 Spring Batch 单元测试的工作示例进行比较,但到目前为止还没有找到任何超出手册的内容!

Spring Batch 单元测试项目包含与创建批处理服务教程完全相同的代码,但有以下例外:

构建.gradle

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:2.1.4.RELEASE")
    }
}

...

dependencies {
    compile("org.springframework.boot:spring-boot-starter-batch");
    compile("org.hsqldb:hsqldb");
    testCompile("junit:junit")
    testCompile("org.springframework.boot:spring-boot-starter-test");
    testCompile("org.springframework.batch:spring-batch-test");
}

和单元测试代码:

应用测试

package hello;

import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.batch.core.JobExecution;
import org.springframework.batch.test.JobLauncherTestUtils;
import org.springframework.batch.test.context.SpringBatchTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import static org.junit.Assert.assertEquals;

@SpringBatchTest
@SpringBootTest
@RunWith(SpringRunner.class)
public class ApplicationTest {

    @Autowired
    private JobLauncherTestUtils jobLauncherTestUtils;

    @Test
    public void testPersonJob() throws Exception {
        JobExecution jobExecution = jobLauncherTestUtils.launchJob();
        assertEquals("COMPLETED", jobExecution.getExitStatus().getExitCode());
    }

}

测试日志显示作业在第一次执行时按预期完成......

2019-05-05 20:30:33.808  INFO 28448 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [FlowJob: [name=importUserJob]] launched with the following parameters: [{run.id=1}]
2019-05-05 20:30:33.886  INFO 28448 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [step1]
2019-05-05 20:30:34.011  INFO 28448 --- [           main] com.example.demo.PersonItemProcessor     : Converting (firstName: Jill, lastName = Doe) into (firstName: JILL, lastName = DOE)
2019-05-05 20:30:34.034  INFO 28448 --- [           main] com.example.demo.PersonItemProcessor     : Converting (firstName: Joe, lastName = Doe) into (firstName: JOE, lastName = DOE)
2019-05-05 20:30:34.034  INFO 28448 --- [           main] com.example.demo.PersonItemProcessor     : Converting (firstName: Justin, lastName = Doe) into (firstName: JUSTIN, lastName = DOE)
2019-05-05 20:30:34.034  INFO 28448 --- [           main] com.example.demo.PersonItemProcessor     : Converting (firstName: Jane, lastName = Doe) into (firstName: JANE, lastName = DOE)
2019-05-05 20:30:34.034  INFO 28448 --- [           main] com.example.demo.PersonItemProcessor     : Converting (firstName: John, lastName = Doe) into (firstName: JOHN, lastName = DOE)
2019-05-05 20:30:34.049  INFO 28448 --- [           main] c.e.d.JobCompletionNotificationListener  : !!! JOB FINISHED! Time to verify the results
2019-05-05 20:30:34.065  INFO 28448 --- [           main] c.e.d.JobCompletionNotificationListener  : Found <firstName: JILL, lastName = DOE> in the database
2019-05-05 20:30:34.065  INFO 28448 --- [           main] c.e.d.JobCompletionNotificationListener  : Found <firstName: JOE, lastName = DOE> in the database
2019-05-05 20:30:34.065  INFO 28448 --- [           main] c.e.d.JobCompletionNotificationListener  : Found <firstName: JUSTIN, lastName = DOE> in the database
2019-05-05 20:30:34.065  INFO 28448 --- [           main] c.e.d.JobCompletionNotificationListener  : Found <firstName: JANE, lastName = DOE> in the database
2019-05-05 20:30:34.065  INFO 28448 --- [           main] c.e.d.JobCompletionNotificationListener  : Found <firstName: JOHN, lastName = DOE> in the database
2019-05-05 20:30:34.065  INFO 28448 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [FlowJob: [name=importUserJob]] completed with the following parameters: [{run.id=1}] and the following status: [COMPLETED]

但是,由于某种原因,同样的 Job 再次意外执行:

2019-05-05 20:30:34.596  INFO 28448 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [FlowJob: [name=importUserJob]] launched with the following parameters: [{random=785577}]
2019-05-05 20:30:34.628  INFO 28448 --- [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [step1]
2019-05-05 20:30:34.659  INFO 28448 --- [           main] com.example.demo.PersonItemProcessor     : Converting (firstName: Jill, lastName = Doe) into (firstName: JILL, lastName = DOE)
2019-05-05 20:30:34.659  INFO 28448 --- [           main] com.example.demo.PersonItemProcessor     : Converting (firstName: Joe, lastName = Doe) into (firstName: JOE, lastName = DOE)
2019-05-05 20:30:34.659  INFO 28448 --- [           main] com.example.demo.PersonItemProcessor     : Converting (firstName: Justin, lastName = Doe) into (firstName: JUSTIN, lastName = DOE)
2019-05-05 20:30:34.659  INFO 28448 --- [           main] com.example.demo.PersonItemProcessor     : Converting (firstName: Jane, lastName = Doe) into (firstName: JANE, lastName = DOE)
2019-05-05 20:30:34.674  INFO 28448 --- [           main] com.example.demo.PersonItemProcessor     : Converting (firstName: John, lastName = Doe) into (firstName: JOHN, lastName = DOE)
2019-05-05 20:30:34.690  INFO 28448 --- [           main] c.e.d.JobCompletionNotificationListener  : !!! JOB FINISHED! Time to verify the results
2019-05-05 20:30:34.690  INFO 28448 --- [           main] c.e.d.JobCompletionNotificationListener  : Found <firstName: JILL, lastName = DOE> in the database
2019-05-05 20:30:34.690  INFO 28448 --- [           main] c.e.d.JobCompletionNotificationListener  : Found <firstName: JOE, lastName = DOE> in the database
2019-05-05 20:30:34.690  INFO 28448 --- [           main] c.e.d.JobCompletionNotificationListener  : Found <firstName: JUSTIN, lastName = DOE> in the database
2019-05-05 20:30:34.690  INFO 28448 --- [           main] c.e.d.JobCompletionNotificationListener  : Found <firstName: JANE, lastName = DOE> in the database
2019-05-05 20:30:34.690  INFO 28448 --- [           main] c.e.d.JobCompletionNotificationListener  : Found <firstName: JOHN, lastName = DOE> in the database
2019-05-05 20:30:34.753  INFO 28448 --- [           main] c.e.d.JobCompletionNotificationListener  : Found <firstName: JILL, lastName = DOE> in the database
2019-05-05 20:30:34.753  INFO 28448 --- [           main] c.e.d.JobCompletionNotificationListener  : Found <firstName: JOE, lastName = DOE> in the database
2019-05-05 20:30:34.753  INFO 28448 --- [           main] c.e.d.JobCompletionNotificationListener  : Found <firstName: JUSTIN, lastName = DOE> in the database
2019-05-05 20:30:34.753  INFO 28448 --- [           main] c.e.d.JobCompletionNotificationListener  : Found <firstName: JANE, lastName = DOE> in the database
2019-05-05 20:30:34.753  INFO 28448 --- [           main] c.e.d.JobCompletionNotificationListener  : Found <firstName: JOHN, lastName = DOE> in the database
2019-05-05 20:30:34.753  INFO 28448 --- [           main] o.s.b.c.l.support.SimpleJobLauncher      : Job: [FlowJob: [name=importUserJob]] completed with the following parameters: [{random=785577}] and the following status: [COMPLETED]

重复执行仅在运行 ApplicationTest 时发生;执行 Spring Boot 应用程序不会重现该问题。

标签: springspring-bootspring-batch

解决方案


Spring 自动运行配置的批处理作业。要禁用作业的自动运行,您需要在 application.properties 文件中使用 spring.batch.job.enabled 属性。

spring.batch.job.enabled=false

推荐阅读