Java 在SpringBatch中测试作业流的最佳方法是什么?

Java 在SpringBatch中测试作业流的最佳方法是什么?,java,testing,spring-batch,Java,Testing,Spring Batch,我有一个复杂的批处理应用程序,我想测试我关于流的假设是否正确 以下是我正在使用的简化版本: <beans> <batch:job id="job1"> <batch:step id="step1" next="step2"> <batch:tasklet ref="someTask1"/> </batch:step> <batch:step id="step2.master">

我有一个复杂的批处理应用程序,我想测试我关于流的假设是否正确

以下是我正在使用的简化版本:

<beans>
  <batch:job id="job1">
    <batch:step id="step1" next="step2">
      <batch:tasklet ref="someTask1"/>
    </batch:step>
    <batch:step id="step2.master">
      <batch:partition partitioner="step2Partitioner"
            step="step2" />
      <batch:next on="*" to="step3" />
      <batch:next on="FAILED" to="step4" />
    </batch:step>
    <batch:step id="step3" next="step3">
      <batch:tasklet ref="someTask1"/>
    </batch:step>
    <batch:step id="step4" next="step4">
      <batch:tasklet ref="someTask1"/>
    </batch:step>
  </batch:job>
  <batch:job id="job2">
    <batch:step id="failingStep">
      <batch:tasklet ref="failingTasklet"/>
    </batch:step>
  </batch:job>

  <bean id="step2Partitioner" class="org.springframework.batch.core.partition.support.MultiResourcePartitioner" scope="step">
    <property name="resources" value="file:${file.test.resources}/*" />
  </bean>

  <bean id="step2" class="org.springframework.batch.core.step.job.JobStep">
    <property name="job" ref="job2" />
    <property name="jobLauncher" ref="jobLauncher" />
    <property name="jobRepository" ref="jobRepository" />
  </bean>
</beans>

Job1是我想测试的工作。我真的只想测试step2.master到step3或step4的转换。我根本不想测试步骤1

但是,我希望保持Job1规范的完整性,因为此测试测试的是配置,而不是底层操作。我已经有验收测试来测试端到端的东西。这个例子就是这样,我可以为小的变化编写有针对性的测试,而无需为每个边缘情况创建单独的端到端测试


我想测试的是,当步骤2中的作业失败时,step2.master会将我转到步骤4,而不是步骤3。有没有好的方法来测试这一点?

您可以用总是失败的模拟实现替换步骤2,并使用StepExecutionListener检查是否调用了步骤3和步骤4

这里有一些很好的例子:
您可以单独测试每个步骤。 例如:

JobLauncherTestUtil JobLauncherTestUtil=新的JobLauncherTestUtil();
jobLauncherTestUtil.setJobLauncher(jobLauncher);
jobLauncherTestUtil.setJob(作业);
jobLauncherTestUtil.setJobRepository(jobRepository);
Map params=Maps.newHashMap();
//在此处确定作业参数:
参数put(…);
JobParameters jobParams=新的JobParameters(参数);
ExecutionContext=新的ExecutionContext();
//如果你需要的话,把一些东西放在工作环境中。
上下文。put(…);
JobExecution JobExecution=JobLaunchTestUtil.launchStep(“stepId”,jobParams,context);
Assert.assertEquals(“步骤stepId失败”,ExitStatus.COMPLETED,execution.getExitStatus())

我希望它能有所帮助。

但是如果step1是一个非常复杂的操作,我不想测试,并且还有其他复杂的操作没有在这个示例中表示,该怎么办?基本上,我只想测试分区作业中的错误是否会将我发送到正确的下一步,而不是正在进行的任何其他操作。您可以使用模拟实现替换复杂作业,这些模拟实现只提供下一个作业所需的任何内容(如果存在任何依赖项)。例如,假设step1读取一个db并在文件夹中生成一个文件。将其替换为将测试文件移动到输出文件夹的模拟。因此,基本上我应该创建第二个配置,以验证另一个配置是否有效。。。是的,我可以很容易地验证“某些”配置是否有效。。。我还可以轻松验证我的特定配置是否有效吗?我会将您的测试分为“测试批处理流是否有效”和“分别测试每个步骤”。要进行测试#1,我将用模拟替换所有实际步骤。为了进行测试#2,我将使用Spring批处理单元测试API,分别启动每个步骤。我正试着围绕这一点思考。我想我误读了你最后的评论。。。基本上,我应该嘲笑工作中步骤的子级,而不是步骤本身,因为我可以自己测试每个小任务或块。对吗?编辑:哈!这一解释是一致的。
JobLauncherTestUtil jobLauncherTestUtil = new JobLauncherTestUtil();
jobLauncherTestUtil.setJobLauncher(jobLauncher);
jobLauncherTestUtil.setJob(job);
jobLauncherTestUtil.setJobRepository(jobRepository);
Map<String, JobParameter> params = Maps.newHashMap();
//determine job params here:
params.put(....);
JobParameters jobParams = new JobParameters(params);
ExecutionContext context = new ExecutionContext();
//put something to job context, if you need.
context.put(...);
JobExecution jobExecution = jobLauncherTestUtil.launchStep("stepId",jobParams,context);

Assert.assertEquals("Step stepId failed", ExitStatus.COMPLETED, execution.getExitStatus())