带退出的TestNg控制台应用程序

时间:2016-11-03 03:14:54

标签: java java-8 testng console-application

我正在尝试为用户输入ESC时的控制台应用编写一个TestNgtest案例。此时应用程序应该打印一条消息然后退出。我希望TestNg测试消息是否被打印。这是应用代码:

public class Application {
  public static void doSomething(Scanner scanner) {
    String inputString = scanner.nextLine();

    if("ESC".equals(inputString.toUpperCase())) {
        System.out.println("Bye");
        System.exit(0);
    }
  }
}

这是junit代码:

public class ApplicationTest {
    private Application app;
    private ByteArrayInputStream in;
    private ByteArrayOutputStream out;

    @BeforeMethod
    public void setUp() throws Exception {
        app = new Application();
        out = new ByteArrayOutputStream();
        System.setOut(new PrintStream(out));
    }

    @AfterMethod
    public void tearDown() throws Exception {
        System.setIn(System.in);
    }

    @Test
    public void testESCInput() throws Exception {
        in = new ByteArrayInputStream("ESC".getBytes());
        System.setIn(in);
        app.processInput(new Scanner(System.in));
        assertTrue(out.toString().contains("Bye"));
    }
}

但是由于应用程序以System.exit退出,我甚至没有进入assertTrue行,因此TestNg在此之前就结束了。有没有正确的方法来测试它?

1 个答案:

答案 0 :(得分:0)

您可以使用SecurityManager拒绝退出尝试,然后围绕预期的异常构建测试,例如这适用于JUnit,应该很容易适应TestNG

public class ExitTest {
  public static class RejectedExitAttempt extends SecurityException {
    private int exitStatus;
    public RejectedExitAttempt(int status) {
      exitStatus=status;
    }
    public int getExitStatus() {
      return exitStatus;
    }
    @Override
    public String getMessage() {
      return "attempted to exit with status "+exitStatus;
    }
  }

  @Before
  public void setUp() throws Exception {
    System.setSecurityManager(new SecurityManager() {
        @Override
        public void checkPermission(Permission perm) {
            if(perm instanceof RuntimePermission && perm.getName().startsWith("exitVM."))
                throw new RejectedExitAttempt(
                    Integer.parseInt(perm.getName().substring("exitVM.".length())));
        }
    });
  }

  @After
  public void tearDown() throws Exception {
    System.setSecurityManager(null);
  }

  @Test(expected=RejectedExitAttempt.class)
  public void test() {
    System.exit(0);
  }
}

这是一个简单的测试,对任何退出尝试都满意。如果需要特定的退出状态,则必须捕获异常并验证状态。

由于此自定义SecurityManager允许执行任何其他操作,因此可以将安全管理器重置为null