Spring批处理步骤中的Mockito Spy SystemCommandTasklet

Spring批处理步骤中的Mockito Spy SystemCommandTasklet,spring,junit,mockito,spring-batch,Spring,Junit,Mockito,Spring Batch,我正在重新分解为Spring批处理作业继承的一个麻烦的测试,该批处理作业调用外部脚本来执行任务。测试的原始版本用一个简单的移动文件脚本替换了真实脚本并启动了作业,然后调用该脚本并测试文件是否正确移动(用于验证是否使用正确的参数调用了脚本) 我对新版本的目标是消除为该测试调用真实脚本的需要,而不是存根和验证用于调用脚本的tasklet的执行方法,依靠Mockito的verify来确保使用了正确的参数 作业的配置如下所示: <flow id="job-flow"> <ste

我正在重新分解为Spring批处理作业继承的一个麻烦的测试,该批处理作业调用外部脚本来执行任务。测试的原始版本用一个简单的移动文件脚本替换了真实脚本并启动了作业,然后调用该脚本并测试文件是否正确移动(用于验证是否使用正确的参数调用了脚本)

我对新版本的目标是消除为该测试调用真实脚本的需要,而不是存根和验证用于调用脚本的tasklet的执行方法,依靠Mockito的verify来确保使用了正确的参数

作业的配置如下所示:

<flow id="job-flow">
    <step id="preprocess" parent="preprocess-base" next="process">
        <tasklet>
            <beans:bean class="com.company.project.main.package.PreprocessTasklet">
                <beans:property name="doMove" value="false" />
            </beans:bean>
        </tasklet>
    </step>
    <step id="process" next="postprocess">
        <tasklet ref="commandTasklet" />
    </step>
    <step id="postprocess" parent="postprocess-base" />
</flow>

<bean id="commandTasklet" class="org.springframework.batch.core.step.tasklet.SystemCommandTasklet" scope="step">
    <property name="command" value="${a.dir}/job_script.sh" />
    <property name="environmentParams" value="working_dir=#{jobExecutionContext['job.dir']}" />
    <property name="workingDirectory" value="${b.dir}" />
    <property name="timeout" value="3600000"/>
</bean>

<batch:job id="run-my-script" parent="base-job" incrementer="defaultIncrementer">
    <batch:flow id="script-job" parent="job-flow" /> 
</batch:job>
}

测试的配置:

<bean class="com.company.test.package.postprocessor.SpiedCommandTaskletPostProcessor" />

有没有更好的方法可以在不实际运行脚本的情况下测试脚本是否使用正确的参数执行?

这里有几个问题:1。运行实际脚本的问题是什么?2.由于属性在对象创建后不会更改,因此可以只执行单个步骤(而不是整个作业)。如果您测试该预处理将job.dir值添加到
ExecutionContext
,则无需在第二步中再次验证它。由于这些脚本实际执行的性质及其周围的配置,无法运行作业将运行的真实脚本。运行伪脚本(正如之前所做的那样)是可行的,但必须配置shell包装器(我们在Windows上开发并部署到Linux),这使得新开发人员的入职或设置CI由于这些外部依赖性而变得更加困难。模拟命令tasklet可以消除这个问题,并使我们的测试更具可移植性。就执行单个步骤而言,这似乎是一个可行的想法,我将尝试一下,看看它是如何工作的。
<bean class="com.company.test.package.postprocessor.SpiedCommandTaskletPostProcessor" />
@Test
public void testLaunch() throws Exception {
    JobExecution jobExecution = getJobLauncher().launchJob(jobParms);
    //Mockito.verify(spiedTasklet).execute(Mockito.any(StepContribution.class), Mockito.any(ChunkContext.class)); spiedTasklet not wired to anything. :(
    assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus());
}