jUnitでSystem.exit(int)を無効にしてみる

unitテストを作ろうと思い、作って実行してみると途中で止まる。。。

「なんで?」

結局のところ、unitテストで実行しようとしたクラスにSystem.exit(int)があったのが原因だった。

それならば、System.exit(int)が効かなくなるおまじないはないかな?
と調べてみたら一応あった。

・テストクラス

public class Target {

    public static void main(String[] args) {
      if (args != null) {
        System.exit(0);
      } else {
        System.exit(-1);
      }
    }
}
・テストケース
import java.security.Permission;

import junit.framework.TestCase;

public class TargetTest extends TestCase {

    final SecurityManager sm = System.getSecurityManager();

    protected void setUp() throws Exception {
      super.setUp();
      // JVMを終了させない
      SecurityManager securityManager = new SecurityManager() {
        public void checkPermission(Permission permission) {
          if ("exitVM".equals(permission.getName())) {
            System.out.println("System.exit[exitVM]が呼ばれた");
          }
        }

        public void checkExit(int status) {
          // super.checkExit(status);
          throw new ExitException(status);
        }
      };
      System.setSecurityManager(securityManager);
    }

    protected void tearDown() throws Exception {
      System.setSecurityManager(sm);
      super.tearDown();
    }

    protected class ExitException extends SecurityException {
      public int state = 0;

      public ExitException(int state) {
        this.state = state;
      }
    }

    public void test引数あり() {
      try {
        Target.main(new String[] {});
      } catch (ExitException e) {
        assertEquals(0, e.state);
      }
    }

    public void test引数なし() {
      try {
        Target.main(null);
      } catch (ExitException e) {
        assertEquals(-1, e.state);
      }
    }
}
とりあえず、これでSystem.exit(int)を呼び出した場合に返されるintのassertも可能。

しかし、ある意味間違ってはないと思うんですが、
そもそも、FileとかSWTとかのからみでのポリシー設定でも何とかなるのかもしれない。。。

しかしながら、djUnitならこんなに悩まなくてもよかったのかもしれないが、
さすがに僕が勝手にライブラリーを増やすわけにはいかないので、
このやり方で当面はやりくりしてみよう。

Posted in ラベル: , , |

0 コメント: