java 如何对java main方法进行单元测试?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34601363/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to unit test java main method?
提问by devlperMoose
I have a class to which I must pass 2 arguments through its main method, if passed less than 2 args, it displays a system error message. I wrote a unit test for the main method here, when I run the test, it stops at "running" (shows neither pass nor fail). Please suggest.
我有一个类,我必须通过它的 main 方法传递 2 个参数,如果传递的参数少于 2 个,它会显示系统错误消息。我在这里为 main 方法编写了一个单元测试,当我运行测试时,它在“运行”时停止(显示既不通过也不失败)。请建议。
Example.java
例子.java
public class Example
{
private static String str1 = null;
private static String str2 = null;
public static void main(String[] args)
{
if( args.length != 2 )
{
call();
}
Example ex = new Example(args[0], args[1]);
ex.getData();
}
public Example(String str1, String str2)
{
Example.str1 = str1;
Example.str2 = str2;
}
public void getData(){
System.out.println("Name is: "+str1);
System.out.println("City is: "+str2);
}
private static void call()
{
System.err.println("Usage: String1 String2");
System.err.println("Where: ");
System.err.println(" String1 - Name");
System.err.println(" String1 - City");
System.exit(1);
}
}
ExampleTest.java
示例测试.java
public class ExampleTest {
@Test
public void testPassingWrongNumberOfInputs() {
StringBuffer sb = new StringBuffer();
sb.append("Usage: String1 String2")
.append("Where: ")
.append(" String1 - Name")
.append(" String1 - City");
String expectedErrorMessage = sb.toString();
ByteArrayOutputStream outContent = new ByteArrayOutputStream();
System.setErr(new PrintStream(outContent));
String[] args = {"one"};
Example.main(args);
assertEquals(expectedErrorMessage, outContent.toString());
}
}
回答by Jose Martinez
How about the following:
以下情况如何:
class TestingSecurityManager extends SecurityManager {
@Override public void checkExit(int status) {
throw new SecurityException();
}
}
Then in your test...
然后在你的测试中...
public class ExampleTest {
@Test
public void testPassingWrongNumberOfInputs() {
StringBuffer sb = new StringBuffer();
sb.append("Usage: String1 String2")
.append("Where: ")
.append(" String1 - Name")
.append(" String1 - City");
String expectedErrorMessage = sb.toString();
ByteArrayOutputStream outContent = new ByteArrayOutputStream();
System.setErr(new PrintStream(outContent));
String[] args = {"one"};
TestSecurityManager sm = new TestSecurityManager ();
System.setSecurityManager(sm);
try {
Example.main(args);
//should throw
fail("Should have thrown exception");
} catch (SecurityException se) {
}
assertEquals(expectedErrorMessage, outContent.toString());
}
}
回答by devlperMoose
I finally was able to write the unit test as shown in the following. I only tested if the method is hitting System.exit(1) code or not.
我终于能够编写如下所示的单元测试。我只测试了该方法是否命中 System.exit(1) 代码。
public class ExampleTest {
private SecurityManager m;
private TestSecurityManager sm;
@Before
public void setUp()
{
m = System.getSecurityManager();
sm = new TestSecurityManager ();
System.setSecurityManager(sm);
}
@After
public void tearDown()
{
System.setSecurityManager(m);
}
@Test
public void testPassingWrongNumberOfInputs() {
try {
Example.main(new String[] {"one"});
} catch (SecurityException se) {
assertEquals("1", se.getMessage());
}
}
}
class TestSecurityManager extends SecurityManager {
@Override
public void checkPermission(Permission permission) {
if ("exitVM".equals(permission.getName()))
{
throw new SecurityException("System.exit attempted and blocked.");
}
}
@Override
public void checkExit(int status) {
throw new SecurityException(Integer.toString(status));
}
}
回答by GregT
Rename the main method, and add a return value, so you can test it. Call this new method from main.
重命名 main 方法,并添加一个返回值,以便您可以对其进行测试。从主调用这个新方法。
回答by Kevin Hooke
Remove the System.exit(1) call, you don't need it. Your app will exit after main() completes anyway without an unneeded call to explicitly terminate the VM. This call is most likely causing your JUnit to stop executing before you get to your assertEquals statement, because you just told the VM to quit.
删除 System.exit(1) 调用,您不需要它。无论如何,您的应用程序将在 main() 完成后退出,而无需调用显式终止 VM。这个调用很可能会导致您的 JUnit 在您到达 assertEquals 语句之前停止执行,因为您只是告诉 VM 退出。