Java: Как проверить методы, которые вызывают System.exit ()? - PullRequest
169 голосов
/ 21 ноября 2008

У меня есть несколько методов, которые должны вызывать System.exit() на определенных входах. К сожалению, тестирование этих случаев приводит к прекращению работы JUnit! Помещение вызовов метода в новый поток, похоже, не помогает, поскольку System.exit() завершает JVM, а не только текущий поток. Существуют ли какие-либо общие модели для решения этой проблемы? Например, можно ли заменить заглушку на System.exit()?

[EDIT] Данный класс на самом деле является инструментом командной строки, который я пытаюсь протестировать в JUnit. Может быть, JUnit просто не подходящий инструмент для работы? Приветствуются предложения по дополнительным инструментам регрессионного тестирования (желательно те, которые хорошо интегрируются с JUnit и EclEmma).

Ответы [ 15 ]

2 голосов
/ 11 июня 2013

Вы можете проверить System.exit (..) с заменой экземпляра среды выполнения. Например. с TestNG + Mockito:

public class ConsoleTest {
    /** Original runtime. */
    private Runtime originalRuntime;

    /** Mocked runtime. */
    private Runtime spyRuntime;

    @BeforeMethod
    public void setUp() {
        originalRuntime = Runtime.getRuntime();
        spyRuntime = spy(originalRuntime);

        // Replace original runtime with a spy (via reflection).
        Utils.setField(Runtime.class, "currentRuntime", spyRuntime);
    }

    @AfterMethod
    public void tearDown() {
        // Recover original runtime.
        Utils.setField(Runtime.class, "currentRuntime", originalRuntime);
    }

    @Test
    public void testSystemExit() {
        // Or anything you want as an answer.
        doNothing().when(spyRuntime).exit(anyInt());

        System.exit(1);

        verify(spyRuntime).exit(1);
    }
}
2 голосов
/ 23 июня 2010

Существуют среды, в которых возвращаемый код завершения используется вызывающей программой (например, ERRORLEVEL в MS Batch). У нас есть тесты по основным методам, которые делают это в нашем коде, и наш подход заключается в использовании аналогичного переопределения SecurityManager, как и в других тестах здесь.

Прошлой ночью я собрал небольшой JAR-файл, используя аннотации Junit @Rule, чтобы скрыть код менеджера безопасности, а также добавить ожидания на основе ожидаемого кода возврата. http://code.google.com/p/junitsystemrules/

1 голос
/ 28 марта 2012

Существует небольшая проблема с решением SecurityManager. Некоторые методы, такие как JFrame.exitOnClose, также вызывают SecurityManager.checkExit. В моем приложении я не хотел, чтобы этот вызов не удался, поэтому я использовал

Class[] stack = getClassContext();
if (stack[1] != JFrame.class && !okToExit) throw new ExitException();
super.checkExit(status);
1 голос
/ 20 октября 2010

Используйте Runtime.exec(String command) для запуска JVM в отдельном процессе.

1 голос
/ 21 ноября 2008

Вызов System.exit () является плохой практикой, если только он не выполняется внутри main (). Эти методы должны вызывать исключение, которое, в конечном счете, перехватывается вашим main (), который затем вызывает System.exit с соответствующим кодом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...