首页 > 解决方案 > 在测试用例中断言 System.out/err

问题描述

我正在考虑通过创建扩展将旧的 junit4 扩展移植到 junit5。到目前为止,我失败的一个功能是使任何在 System.out 或 System.err 上写入的测试方法都失败,并将失败点指向该特定测试。

我尝试将 TestExecutionListener#reportingEntryPublished 与 junit.jupiter.extensions.autodetection.enabled=true 一起使用,然后我使用了该方法,但是此时实际上将测试状态更改为 FAILED 为时已晚。或者我可以吗?

我开始使用 BeforeAllCallback 和 AfterAllCallback 并进行 out/err 重定向并在字符串缓冲区上断言。我可能能够让它工作,但这似乎是我可能会搞砸的事情,并且从现在起几年后会发现错误:) 我们的 junit4 跑步者做了这样的事情,但它真的过于复杂,我不希望任何人尝试维护类似的东西。

有什么办法可以在junit5中很好地做到这一点?

标签: junit5junit5-extension-model

解决方案


我最终做的是创建一个实现 BeforeEachCallback、AfterEachCallback 的类,并将 beforeEach 期间的每个 stderr/out 重定向到一个自定义打印流,每个打印流存储所有接收到的输出。然后在 afterEach 期间,我询问打印流是否收到任何东西。如果有,那么我抛出自定义流根据第一次打印调用时修改的堆栈跟踪生成的 AssertionError。然后将 out/err 重置为原始流。这允许使用一些技巧来允许将输出打印到控制台而不会引发错误,并且仍然将测试用例标记为失败,并带有关于不允许输出的自定义消息。

此解决方案中存在一些潜在的缺陷,例如,我尝试调用 Logger 的其他扩展类之一中的错误会产生一些可疑的情况。对于我们的用例,它应该足够了。

由于我的雇主有很多障碍要跳过才能被允许在外部共享代码,不幸的是,我无法为其他需要做同样事情的人这样做,但应该能够弄清楚如何体面地做到这一点基于以上。


推荐阅读