单元测试弹簧批量作业

时间:2012-10-30 09:20:18

标签: junit spring-batch

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

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

2)一个包含几个步骤的作业,其中一些步骤包含itemreader,itemprocessor,itemwriters,而一些步骤包含tasklet。

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

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

1 个答案:

答案 0 :(得分:7)

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

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

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

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

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

    您需要在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[] {});
      }
    });
    

    使用上面的代码,您可以断言批处理失败时使用正确的值调用System.exit(),也允许测试失败条件。

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