【问题标题】:Unit testing spring batch jobs单元测试春季批处理作业
【发布时间】:2012-10-19 14:39:04
【问题描述】:

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

1) 一个独立的 tasklet 在 spring 批处理作业的一个 step 中运行。

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

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

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

【问题讨论】:

  • 一般注意事项:确保您最终不会编写有效测试数据库或 Spring Batch 的测试。这意味着您可以使用以下技术(即使用 HSQLDB)来模拟数据库及其表。这可以使用内存数据库完成,因此比使用真实数据库要快很多倍。

标签: junit spring-batch


【解决方案1】:

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

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

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

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

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

有几个警告:

您需要在 SecurityManager 中运行 main 方法。如果您的 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 启动它,在故障安全插件运行。有时这可能有点繁琐。

【讨论】:

猜你喜欢
  • 2020-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-17
  • 2018-10-04
  • 2018-02-23
  • 1970-01-01
相关资源
最近更新 更多