我想测试一些使用 3rd 方代码调用的代码,kotlin.system.exitProcess()
在标准库中定义如下:
@kotlin.internal.InlineOnly
public inline fun exitProcess(status: Int): Nothing {
System.exit(status)
throw RuntimeException("System.exit returned normally, while it was supposed to halt JVM.")
}
当exitProcess()
被调用时,JVM 停止并且无法进行进一步的测试。我没有设法exitProcess()
用 mockk 模拟调用。可能吗?
一些进一步的信息:
第 3 方库是 Clikt ( https://ajalt.github.io/clikt/ ),这是一个用于构建命令行界面的好库。Clikt 应用程序解析命令行,如果失败则退出。这可能是调用 System.exit 可以的罕见原因之一。当然还有更多可测试的解决方案,但无论如何,在使用 3rd 方库时,争论在库中可以更好地完成的事情已经过时了。
我真正想要测试的是,我的应用程序在使用--help或错误参数调用时会写入预期的使用消息。
我还尝试以System.exit()
这种方式模拟调用: mockkStatic("java.lang.System") every { System.exit(any()) }.throws(RuntimeException("blubb")) 导致另一个问题,也都是然后模拟对 System 的调用:
io.mockk.MockKException: every/verify {} block were run several times. Recorded calls count differ between runs
Round 1: class java.lang.System.getProperty(kotlin.ignore.old.metadata), class java.lang.System.exit(-630127373)
Round 2: class java.lang.System.exit(158522875)
有趣的是,我设法用 jmockit 在 Java 中对此进行了测试,如下所示:
public class MainTestJ {
private ByteArrayOutputStream consoleOut;
@BeforeEach
public void mockConsole() {
consoleOut = new ByteArrayOutputStream();
System.setOut(new PrintStream(consoleOut));
}
@Test
public void can_mock_exit() {
new MockUp<System>() {
@Mock
public void exit(int exitCode) {
System.out.println("exit called");
}
};
assertThatThrownBy(() -> {
new Main().main(new String[] { "--help" });
}).isInstanceOf(RuntimeException.class);
assertThat(consoleOut.toString()).startsWith("Usage: bla bla ...");
}
}