All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.junit.contrib.java.lang.system.ExpectedSystemExit Maven / Gradle / Ivy

package org.junit.contrib.java.lang.system;

import static java.lang.System.getSecurityManager;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import java.util.ArrayList;
import java.util.Collection;

import org.junit.contrib.java.lang.system.internal.CheckExitCalled;
import org.junit.contrib.java.lang.system.internal.NoExitSecurityManager;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;

/**
 * The {@code ExpectedSystemExit} allows in-test specification of expected
 * {@code System.exit(...)} calls.
 *
 * 

* If your code calls {@code System.exit(),} then your test stops and doesn't * finish. The {@code ExpectedSystemExit} rule allows in-test specification of * expected {@code System.exit()} calls. Furthermore you cannot use JUnit's * assert methods because of the abnormal termination of your code. As a * substitute you can provide an {@code Assertion} object to the * {@code ExpectedSystemExit} rule. * *

* Some care must be taken if your system under test creates a new thread and * this thread calls {@code System.exit()}. In this case you have to ensure that * the test does not finish before {@code System.exit()} is called. * *

 * public class AppWithExit {
 * 	public static String message;
 *
 * 	public static int doSomethingAndExit() {
 * 		message = "exit ...";
 * 		System.exit(1);
 * 	}
 *
 * 	public static int doNothing() {
 * 	}
 * }
 * 
* *
 * public void AppWithExitTest {
 *   @Rule
 *   public final ExpectedSystemExit exit = ExpectedSystemExit.none();
 *
 *   @Test
 *   public void exits() {
 *     exit.expectSystemExit();
 *     AppWithExit.doSomethingAndExit();
 *   }
 *
 *   @Test
 *   public void exitsWithStatusCode1() {
 *     exit.expectSystemExitWithStatus(1);
 *     AppWithExit.doSomethingAndExit();
 *   }
 *
 *   @Test
 *   public void writesMessage() {
 *     exit.checkAssertionAfterwards(new Assertion() {
 *       public void checkAssertion() {
 *         assertEquals("exit ...", AppWithExit.message);
 *       }
 *     });
 *     AppWithExit.doSomethingAndExit();
 *   }
 *
 *   @Test
 *   public void systemExitWithStatusCode1() {
 *     exit.expectSystemExitWithStatus(1);
 *     AppWithExit.doSomethingAndExit();
 *   }
 *
 *   @Test
 *   public void noSystemExit() {
 *     AppWithExit.doNothing();
 *     //passes
 *   }
 * }
 * 
*/ public class ExpectedSystemExit implements TestRule { public static ExpectedSystemExit none() { return new ExpectedSystemExit(); } private final Collection assertions = new ArrayList(); private boolean expectExit = false; private Integer expectedStatus = null; private ExpectedSystemExit() { } public void expectSystemExitWithStatus(int status) { expectSystemExit(); expectedStatus = status; } public void expectSystemExit() { expectExit = true; } public void checkAssertionAfterwards(Assertion assertion) { assertions.add(assertion); } public Statement apply(final Statement base, Description description) { ProvideSecurityManager noExitSecurityManagerRule = createNoExitSecurityManagerRule(); Statement statement = createStatement(base); return noExitSecurityManagerRule.apply(statement, description); } private ProvideSecurityManager createNoExitSecurityManagerRule() { NoExitSecurityManager noExitSecurityManager = new NoExitSecurityManager( getSecurityManager()); return new ProvideSecurityManager(noExitSecurityManager); } private Statement createStatement(final Statement base) { return new Statement() { @Override public void evaluate() throws Throwable { try { base.evaluate(); } catch (CheckExitCalled ignored) { } checkSystemExit(); checkAssertions(); } }; } private void checkSystemExit() { NoExitSecurityManager securityManager = (NoExitSecurityManager) getSecurityManager(); if (securityManager.isCheckExitCalled()) handleSystemExitWithStatus(securityManager.getStatusOfFirstCheckExitCall()); else handleMissingSystemExit(); } private void handleMissingSystemExit() { if (expectExit) fail("System.exit has not been called."); } private void handleSystemExitWithStatus(int status) { if (!expectExit) fail("Unexpected call of System.exit(" + status + ")."); else if (expectedStatus != null) assertEquals("Wrong exit status", expectedStatus, Integer.valueOf(status)); } private void checkAssertions() throws Exception { for (Assertion assertion : assertions) assertion.checkAssertion(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy