如何在 junit5 中测试日志记录?



我正在一个项目上从 junit4 过渡到 junit5,并试图弄清楚如何测试日志。 以前,我使用

@Rule
OutputCapture outputCapture = new OutputCapture();

然后会使用outputCapture.toString()编写断言,例如

assertThat(outputCapture.toString(),containsString("status=200"));

由于 junit5 中尚未实现@Rule注释,因此我无法使用 outputCapture。 有什么想法吗? 谢谢!

为此提供了一个扩展,您可以按如下方式使用它:

@ExtendWith(OutputCaptureExtension.class)
public class MyTestClass {
@Test
void myTestCase(CapturedOutput capturedOutput) {
assertTrue(capturedOutput.getOut().contains("expected string"));
assertTrue(capturedOutput.getErr().contains("expected string"));
}
}

我们在 JUnit5 迁移过程中偶然发现了同样的问题。经过一番研究,我找到了一个技术解决方案,但似乎还没有人用它制作测试库。这就是我所做的。它已发布到 Maven Central,因此您可以立即使用它:

https://github.com/netmikey/logunit

您可以按如下方式使用它:

public class MyModuleTest {
@RegisterExtension
LogCapturer logs = LogCapturer.create().captureForType(MyModule.class);
@Test
public void testLogging() {
// ... do the testing ...
// Run assertions on the logged messages
logs.assertContains("Some message");
}
}

(有关更多示例,请参阅项目的自述文件)

JUnit5 文档中的迁移提示明确指出 -

@Rule@ClassRule不再存在;由@ExtendWith取代;有关部分规则支持,请参阅以下部分。

为了使用 JUnit 4 中现有的@Rule支持,建议使用一种方法或类级注释。

与 JUnit 4 一样,支持规则注释字段以及方法。 通过在测试类上使用这些类级扩展,例如规则 遗留代码库中的实现可以保持不变,包括 JUnit 4 规则导入语句。

这种有限形式的规则支持可以通过 类级注释org.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport


更好的选择仍然是重新设计测试套件以使用JUnit5中的扩展模型(如果您正在使用它)。

您还可以通过快速实现自己的解决方案来轻松测试写入System.out的日志输出,如下所示:

// Configure System.out to be written to a buffer from which we can read
PrintStream realSysOut = System.out;
BufferedOutputStream sysOutBuffer = new ByteArrayOutputStream();
System.setOut(new PrintStream(sysOutBuffer));
...
// Perform some action which logs something to System.out
System.out.println("Some random content written to System.out");
...
// Assert that a given string was written in the meantime to System.out
assertThat(new String(buffer.toByteArray()), containsString("random content"));
...
// Don't forget to bring back the real System.out at the end of the test
System.setOut(realSysOut);

在检查写入 System.err 的日志输出的情况下,您可以通过将System.setOut(...) 替换为System.setErr(...) 并将 System.out替换为上述示例中的System.err来等效地实现它。

最新更新