Я хочу протестировать некоторый код, который использует сторонний код, который вызывает 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()
с помощью макета.Возможно ли это?
Некоторая дополнительная информация:
Сторонней библиотекой является Clikt (https://ajalt.github.io/clikt/), хорошая библиотека для создания интерфейса командной строки. Приложение Clikt анализирует командную строкуи завершается, если это не удается. Это может быть одной из редких причин, когда вызывается System.exit. Конечно, есть более тестируемые решения, но в любом случае, при работе со сторонними библиотеками, спорят, что можно сделать лучше в библиотека устарела.
Что я на самом деле хочу проверить, так это то, что мое приложение записывает ожидаемое сообщение об использовании при вызове с - справка или неверные аргументы.
Я также пытался смоделировать вызов 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)
Как ни странно, мне удалось проверить это на Java с помощью jmockit, например:
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 ...");
}
}