How to test System.exit: Difference between revisions
No edit summary |
mNo edit summary |
||
Line 72: | Line 72: | ||
} | } | ||
</pre> | </pre> | ||
[[Category:Java]] |
Latest revision as of 22:33, 30 September 2007
One might assume that testing a console app method which calls System.exit() would be impossible to do. By creating a SecurityManager we can detect and defer this call.
import java.io.IOException; import java.security.Permission; import java.util.Stack; public class ConsoleAppUnitTest extends UnitTestCase { private SecurityManager existingSecurityManager; @Override protected void setUp() throws Exception { existingSecurityManager = System.getSecurityManager(); } @Override protected void tearDown() throws Exception { System.setSecurityManager(existingSecurityManager); } private static class ExitCatchingSecurityManager extends SecurityManager { private Stack<Integer> exitCodes = new Stack<Integer>(); public void checkExit(int status) { exitCodes.push(status); throw new SecurityException(); } /** * This method is called before the original security manager can be replaced. If this method does * not throw and exception then 'System.setSecurityManager(existingSecurityManager)' will work. * @param perm anything */ @Override public void checkPermission(Permission perm) { } public int getLastExit() { return exitCodes.pop(); } } public void testNoArgsExitsWithReturnCode() { ExitCatchingSecurityManager securityManager = new ExitCatchingSecurityManager(); try { System.setSecurityManager(securityManager); ConsoleApp.main(new String[] { }); fail(); } catch (SecurityException e) { pass(); assertEquals(2, securityManager.getLastExit()); assertEquals(1, securityManager.getLastExit()); } } }
System.exit is called twice in this case, because the first System.exit throws an SecurityException which is caught in the 'catch Throwable' line. This trys to call System.exit again, and ends up throwing another exception.
@SuppressWarnings({ "CallToSystemExit" }) public static void main(String[] args) { try { if (args.length != 2) { System.err.println("Usage: inputFile outputFile"); System.exit(1); } new ConsoleApp(args[0], args[1]).run(); } catch (Throwable t) { t.printStackTrace(System.err); System.exit(2); } }