Тестирование методов с System.exit() в JUnit: решения
Быстрый ответ
// С помощью правила ExpectedSystemExit из JUnit вы можете перехватить вызов System.exit.
import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.ExpectedSystemExit;
public class GhostProgrammer {
@Rule
public final ExpectedSystemExit exit = ExpectedSystemExit.none();
@Test
public void actuallyExits() {
exit.expectSystemExit();
System.exit(42); // Возможно, мы нашли ответ на вопрос о смысле жизни, вселенной и всего такого!
}
}
С помощью этого подхода вы перехватываете системный вызов выхода и предотвращаете завершение работы JVM во время тестирования!
Альтернативы вызову выхода
Если использование ExpectedSystemExit
не подходит для вас столько же, сколько и ананас на пицце, мы предлагаем другие варианты:
Агрессивный пацифист: неуправляемые исключения
public void gracefulShutdown(int status) {
throw new RuntimeException("Розы красные, моя любовь к тестам бездонна, завершаем с кодом " + status);
}
JVM не завершает работу, но изящество ситуации нарушается через обработку исключений.
Превентивный родитель: Собственный SecurityManager
public class ConservativeSecurityManager extends SecurityManager {
@Override
public void checkExit(int status) {
super.checkExit(status);
throw new SecurityException("Куда собрались, молодой человек?!");
}
}
Это подобно запрету на опоздания после комендантского часа! SecurityException
: вы попались!
Шепчущий за кулисами: System Lambda
import static com.github.stefanbirkner.systemlambda.SystemLambda.catchSystemExit;
public class SneakyCode {
@Test
public void exitsLikeANinja() {
int status = catchSystemExit(() -> {
System.exit(0); // Как ниндзя, не оставляющий за собой следов.
});
assertEquals(0, status); // Следы остыли.
}
}
System Lambda — это библиотека для любителей тестирования, предпочитающих использовать Java 8+.
Визуализация
// мой код не работает? Возможно, проблема во мне самом.
Основная идея тестирования такова:
Вместо того чтобы позволить коду исчезнуть, словно испариться через дверь с надписью EXIT 🚪💨,
вы говорите ему: "Беги, функция, беги!" 🏃💨, но затем можете остановить его посреди пути 🛑✋
Способы перехвата:
1. Борьба за голосование: замените стандартный `SecurityManager` своим [🛡]
("Тимми, нельзя выходить, пока ты не съешь брокколи!")
2. Будучи маршалом: используйте библиотеку `System Rules` для установки правил [📜➡️🔏]
3. Невидимый страж: ожидайте вызова 'exit' с помощью `ExpectedException` от JUnit [👀🚨]
Продвинутые стратегии
Выполнение вышеуказанных инструкций, вероятно, поможет решить вашу проблему с методами, вызывающими "system-exit". Однако, если ваша задача кажется ещё более сложной, рассмотрите следующие опции:
Java 21+: Новый порядок
В эпоху Java 21 вводится новый параметр -Djava.security.manager=allow
. Убедитесь, что он установлен правильно!
Изменения глобального состояния: Корректируем эффект бабочки
Если вы изменили глобальное состояние (например, статическую переменную), исправьте это, откатив эти изменения перед тестированием и после его завершения.
Инструменты покрытия: Шпион, которого я люблю
Инструменты, такие как EclEmma, разработаны для анализа покрытия кода тестами и требуют корректного завершения программы для точного отчета. Проверьте их совместимость.
Непрерывная интеграция: Великое представление
На этапе CI-пайплайна, неожиданный вызов System.exit()
может прекратить исполнение сценария! Учтите перечисленные стратегии, чтобы шоу продолжилось.
Полезные материалы
- java – Как тестировать методы, которые вызывают System.exit()? Обсуждение на Stack Overflow о лучших способах тестирования System.exit().
- System Rules Библиотека, прямая и по существу. Рекомендуется к ознакомлению.
- SecurityManager (Java Platform SE 8 ) Официальная документация от Oracle. Нет, System.exit() не был создан, чтобы запутать вас.
- Пользовательское руководство JUnit 5 Когда ваши тесты отказываются смотреть на вещи вашими глазами.
- GitHub – powermock/powermock: PowerMock – Java-фреймворк, который позволяет тестировать код, который обычно не тестируют. Мощный фреймворк для создания моков. Постарайтесь уделить ему внимание.
- Lang – Home Это не просто библиотека Apache. Она действительно необычайна!
- Стоит ли мгновения... Несмотря на свою краткость, этот материал может быть очень полезным для ваших тестов в долгосрочной перспективе.