JUnit单元测试7—系统退出状态码

如果被测方法中存在系统退出语句,测试过程会直接终止,测试方法无法获取System.exit(statusCode);语句中的状态码。


如果需要在测试方法中对系统退出状态码进行判断,可以通过覆盖Java默认的SecurityManager来实现。
因为System.exit(statusCode)实际会将退出操作委托给Runtime类,Runtime类在执行Shutdown前会先调用当前VM的SecurityManager的checkExit(statusCode)方法,如果checkExit抛出异常,则系统退出终止。

因此我们可以重写SecurityManager的checkExit方法,通过抛出异常的方式将statusCode传递出来。

示例程序

下面程序演示如何在测试方法中执行main方法,并获取其退出状态码。

  • 被测程序
public class HelloWorld {
    public static void main(String[] args) {
        System.exit(1);
    }
}
  • 自定义SecurityManager类
    注意:需要重写checkPermission方法为空方法。
import java.security.Permission;

public class ExitCheckSecurityManager extends SecurityManager {
    /**
     * 临时托管系统原有SecurityManager
     */
    private SecurityManager delegateSecurityManager;

    public ExitCheckSecurityManager(SecurityManager delegateSecurityManager) {
        this.delegateSecurityManager = delegateSecurityManager;
    }

    @Override
    public void checkExit(int status) {
        super.checkExit(status);
        System.setSecurityManager(this.delegateSecurityManager);
        throw new ExitSecurityException(status);
    }

    @Override
    public void checkPermission(Permission permission) {
    }

    public static class ExitSecurityException extends SecurityException {
        public final int status;

        public ExitSecurityException(int status) {
            this.status = status;
        }
    }
}
  • 测试类
import static org.junit.Assert.*;

import org.junit.Test;

public class HelloWorldTest {

    @Test
    public void testMain() {
        System.setSecurityManager(new ExitCheckSecurityManager(System.getSecurityManager()));
        try {
            HelloWorld.main(null);
            fail();
        } catch (ExitCheckSecurityManager.ExitSecurityException e) {
            assertEquals(1, e.status);
        }
    }
}

上一篇:JUnit单元测试6—@Rule注解

你可能感兴趣的:(JUnit单元测试7—系统退出状态码)