如何测试从数据库读取并写入文件的弹簧批处理步骤?
Posted
技术标签:
【中文标题】如何测试从数据库读取并写入文件的弹簧批处理步骤?【英文标题】:How to test spring batch step which reads from database and writes into a file? 【发布时间】:2018-08-23 10:14:29 【问题描述】:我想知道在 Spring Batch 作业中测试以下场景的最佳方法是什么:
由两个步骤组成的作业:1) 第一步使用ItemReader
(from apache kudu using impala
) 从数据库中读取数据并将查询生成的内容写入文件。
itemReader
有一个 rowMapper
,它从结果集中创建一个复杂对象。它的itemWriter
只是为那个复杂对象创建了一个toString (which in fact is a JSON representation)
。
2) 第二步从step 1
生成的文件中读取并处理。处理完所有文件后,将所有内容写入一个新文件。
itemReader
使用jsonLineMapper
从step 1
读取文件,然后处理从映射器生成的新复杂对象并将它们写入新文件。
然后作业的监听器将这两个文件上传到 S3。
我需要这个工作流程,因为第一步会生成第二步所需的样本。如果有一天我只需要测试第二步,我可以使用第一步中的旧样本,因为数据库会随着时间而变化,如果没有它,我可能无法生成两天前执行的相同样本。
第一步是最难测试的,但我想以如下方式测试这两个步骤:
1) 来自step 1
我需要检查查询语法是否正确。此外,检查数据库结果集中是否通过rowMapper
生成正确的对象。 itemWriter
的文件内容是正确的(correct means that is expected)
。
2) 第二步更容易测试,因为我可以从预定义的文件开始。它应该测试使用jsonLineMapper
从文件中读取是否正确完成。处理部分是分开测试的,但我可以遵循一个简单的工作流程,最终文件具有预期的内容。
我测试该场景的想法是:
1) 为了检查查询语法是否正确,我需要一个查询构建器(我用谷歌搜索并找到了像 jOOQ
这样的库,但我不想添加一个外部库只是为了构建一个字符串查询) .在检查查询是否正确之后,也许我应该mock
数据库并返回一个预定义的复杂对象并将其写入文件中。问题是,如果查询返回缺少的列,则该对象将不正确,并且测试应该失败,所以如果我返回一个预定义的对象,我将永远不知道哪个是查询返回。
正如您在此处看到的那样,问题出现在验证查询时,如果查询正确,我可以测试rowMapper
和最终文件。
2) 对于这一步,我认为最好的方法是使用来自step 1
的正确内容的预定义文件,然后检查最终文件内容是否符合我的预期。我认为这一步很容易测试。
有什么更好的方法来测试这个场景吗?
谢谢!
【问题讨论】:
【参考方案1】:对于第 1 步,我建议使用嵌入式数据库插入一些行,运行您的作业,然后断言生成的文件是正确的。这使您可以控制测试数据,以验证您的查询和文件中的预期结果。您可以在此处找到示例:https://docs.spring.io/spring-batch/4.0.x/reference/html/testing.html#endToEndTesting。 Spring Batch 提供AssertFile.assertFileEquals
来测试两个文件是否相等。这可以帮助您根据预期文件验证步骤 1 的输出。
对于第 2 步,您可以创建一些有效/无效文件(可能是第 1 步的结果)并将它们用作测试第 2 步的输入。但需要注意的是,如果第 1 步的结果发生变化,这些文件将不再对测试步骤 2 有效(因此这是您需要注意的维护成本)。
【讨论】:
感谢您的回答!问题是我无法嵌入任何数据库,因为 PostgreSQL 的连接表语法与 Impala 不同。我正在使用 Impala 查询 Apache Kudu,但我没有找到任何嵌入 Impala 和 Kudu 的方法。 确实,当您无法在嵌入式模式下使用真实数据库或数据库供应商之间的语法不同时,这是一个问题。您仍然可以使用相同的方法使用真实数据库而不是嵌入式数据库来测试第 1 步。 这是我一开始要做的,但我想知道是否有更好的方法,因为如果数据库(测试数据库)关闭,测试就会失败。但我想我会试试你的方法,谢谢! 您可以在测试之前/之后使用测试容器来启动/停止数据库容器。更多细节在这里:testcontainers.org/usage/database_containers.html#junit-rule。这使您可以避免“如果测试数据库关闭,则测试将失败”的情况。以上是关于如何测试从数据库读取并写入文件的弹簧批处理步骤?的主要内容,如果未能解决你的问题,请参考以下文章