为什么System.exit()?而不是使用System.exit(whateverValue)终止,为什么不抛出未经检查的异常?在正常使用中,它将一直漂移到JVM的最后一个捕获器并关闭你的脚本(除非你决定在途中捕获它,这可能在某一天有用)。
在JUnit场景中,它将被JUnit框架捕获,该框架将报告此类测试失败并顺利地移动到下一个。防止System.exit()实际退出JVM:尝试修改TestCase以使用安全管理器运行,该管理器阻止调用System.exit,然后捕获SecurityException。public class NoExitTestCase extends TestCase {
protected static class ExitException extends SecurityException
{
public final int status;
public ExitException(int status)
{
super("There is no escape!");
this.status = status;
}
}
private static class NoExitSecurityManager extends SecurityManager
{
@Override
public void checkPermission(Permission perm)
{
// allow anything.
}
@Override
public void checkPermission(Permission perm, Object context)
{
// allow anything.
}
@Override
public void checkExit(int status)
{
super.checkExit(status);
throw new ExitException(status);
}
}
@Override
protected void setUp() throws Exception
{
super.setUp();
System.setSecurityManager(new NoExitSecurityManager());
}
@Override
protected void tearDown() throws Exception
{
System.setSecurityManager(null); // or save and restore original
super.tearDown();
}
public void testNoExit() throws Exception
{
System.out.println("Printing works");
}
public void testExit() throws Exception
{
try
{
System.exit(42);
} catch (ExitException e)
{
assertEquals("Exit status", 42, e.status);
}
}}
2012年12月更新:
将在评论中使用系统规则提出一系列JUnit(4.9+)规则来测试使用的代码java.lang.System。
这是回答中最初提到的。System.exit(…)使用该ExpectedSystemExit规则验证是否System.exit(…)已调用。
您也可以验证退出状态。
例如:public void MyTest {
@Rule
public final ExpectedSystemExit exit = ExpectedSystemExit.none();
@Test
public void noSystemExit() {
//passes
}
@Test
public void systemExitWithArbitraryStatusCode() {
exit.expectSystemExit();
System.exit(0);
}
@Test
public void systemExitWithSelectedStatusCode0() {
exit.expectSystemExitWithStatus(0);
System.exit(0);
}}