[英]Test console output using JUnit
我正在尝试使用JUnit测试另一个程序的控制台输出。 我按照这里给出的答案
这是我的JUnit类
import static org.junit.Assert.*;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import org.junit.*;
public class MainTest {
private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
private final ByteArrayOutputStream errContent = new ByteArrayOutputStream();
@Before
public void setup() {
System.setOut(new PrintStream(outContent));
System.setErr(new PrintStream(errContent));
}
@Test
public void test01_initTest() {
String[] arguments = {"a", "b"};
Main.main(arguments);
String expected = "hello";
assertTrue(expected == outContent.toString());
}
@After
public void cleanUpStreams() {
System.setOut(null);
System.setErr(null);
}
}
当我在Eclipse中运行该程序时,都看不到控制台输出,并且测试运行没有结束。 但是,如果我直接从test01_initTest()在控制台上打印输出,则测试通过。 要检查Main.main()是否已打印出来,我还尝试了以下代码,在这种情况下,我确实看到了控制台输出
import static org.junit.Assert.*;
import org.junit.*;
public class MainTest {
@Test
public void test01_initTest() {
String[] arguments = {"a", "b"};
Main.main(arguments);
}
}
我累了很多事情,但是我无法弄清楚我在做什么错。 有人可以帮我吗。
如果您正在测试的代码调用System.exit()
则JUnit无法正常完成。
如果该主线程终止,则JUnit将挂起。
解决方法是使用SecurityManager
防止调用System.exit()
在另一个StackOverflow答案中,我描述了如何编写这样的SecurityManager:
(为防万一,此处复制的代码)。
调用System.exit()
时,此SecurityManager将引发自定义TriedToExitException
,并保留退出代码,以便您可以捕获异常并测试是否使用了正确的退出代码。
/**
* A special implementation of {@link SecurityManager}
* that will throw a {@link TriedToExitException}
* if {@link System#exit(int)} is called.
* This is useful for testing main methods
* without shutting
* down the jvm running junit.
* Tests can catch {@link TriedToExitException}
* to figure out what exit code was set.
*/
public static final SecurityManager NON_EXITABLE_MANAGER = new SecurityManager(){
@Override
public void checkPermission(Permission perm) {
//allow everything
}
/**
* Throws a {@link TriedToExitException} instead of exiting.
* <p/>
* {@inheritDoc}
*/
@Override
public void checkExit(int status) {
throw new TriedToExitException(status);
}
};
public static final class TriedToExitException extends SecurityException{
private static final long serialVersionUID = 1L;
private final int exitCode;
public TriedToExitException(int exitCode){
this.exitCode=exitCode;
}
@Override
public String getMessage() {
return String.format("tried to System.exit(%d)",exitCode);
}
public int getExitCode() {
return exitCode;
}
然后在您的单元测试中,将我们的SecurityManager替换为我们的版本,该版本停止调用退出(并保存旧的SecurityManager,以便我们在测试后可以将其还原)
private SecurityManager previousManager=null;
@Before
protected void replaceManager() throws Throwable {
previousManager = System.getSecurityManager();
System.setSecurityManager(NON_EXITABLE_MANAGER);
}
@After
protected void restoreManager() {
System.setSecurityManager(previousManager);
}
@Test
public void testCallToExit() throws IOException{
try{
//something that calls System.exit
fail("should call exit");
}catch(TriedToExitException e){
//make sure we get correct exit code
assertEquals(-1, e.getExitCode());
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.