单元测试弹簧批量作业

Vic*_*cky 4 junit spring-batch

在Spring Batch作业中测试以下场景的方法是什么:

1)在弹簧批处理作业中的一个步骤中运行的独立tasklet.

2)一个由几个步骤组成的作业,其中一些步骤具有itemreader,itemprocessor,itemwriters,而一些步骤具有tasklet.

3)项目阅读器,其中对项目阅读器的输入查询是一个非常复杂的SQL查询,具有来自许多表的连接 - 这种情况不允许清空所有使用的表并用虚拟数据填充它们以进行测试.换句话说,可能存在真实世界场景,其中无法清空表格以进行测试.那种情况应该是什么方法?

如果我在这个论坛上得到一些关于要采取的方法的帮助,我想准备一个示例套件,其中包含测试具有不同作业场景的spring批处理作业的示例.

Mat*_*ell 7

"单元"测试弹簧批处理作业非常困难,纯粹是因为与外部资源(例如数据库或文件等)的交互很多.我的方法有两个层次:

tasklet中的各个方法都是正常的单元测试,我只是直接从JUnit测试中调用方法,使用通常的模拟或存根.

其次,我从JUnit测试中运行批处理,直接调用main方法,并使用所有必要的基础结构.对于我的批处理作业,我需要一个数据库和一些输入文件.我的JUnit测试将该测试的所有必要文件复制到临时目录(我通常使用maven target/it),以及数据库(我有以HSQLDB格式保存的MySQL数据库的副本).然后我Main.main()直接使用正确的参数调用,让批处理运行然后检查结果,检查是否生成了正确的文件,数据库是否已正确更改等.

作为一种工作方式,这有几个优点.

  1. 我可以从Eclipse运行这些测试,因此缩短了调试周期,因为我不需要每次都构建完整的包来测试它.
  2. 它们很容易包含在构建中,我只是将它们包含在maven的failsafe插件中.

有几个警告:

您需要在SecurityManager中运行main方法.如果您的主要调用System.exit(),则不希望JVM停止.有关SecurityManager的示例,请参阅org.junit.tests.running.core.MainRunner.这被称为:

Integer exitValue = new MainRunner().runWithCheckForSystemExit(new Runnable() {
    public void run() {
    Main.main(new String[] {});
  }
});
Run Code Online (Sandbox Code Playgroud)

使用上面的内容,您可以声明批处理失败时使用正确的值调用System.exit(),从而允许测试失败条件.

其次,您可以从JUnit测试中进行大量设置,但是您无法完成所有操作,因此,例如,如果您需要FTP服务器,我通常从maven而不是JUnit启动它,然后故障安全插件运行.有时这可能有点繁琐.