我正在尝试为用户输入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在此之前就结束了。有没有正确的方法来测试它?
答案 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
。