简体   繁体   English

如何单元测试java main方法?

[英]How to unit test java main method?

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. 我有一个类,我必须通过它的main方法传递2个参数,如果传递少于2个args,它会显示一个系统错误消息。 I wrote a unit test for the main method here, when I run the test, it stops at "running" (shows neither pass nor fail). 我在这里为main方法编写了一个单元测试,当我运行测试时,它停止在“running”(显示既不通过也不失败)。 Please suggest. 请建议。

Example.java Example.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 ExampleTest.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());
    }
}

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());
    }
}

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));
    }
}

Remove the System.exit(1) call, you don't need it. 删除System.exit(1)调用,您不需要它。 Your app will exit after main() completes anyway without an unneeded call to explicitly terminate the VM. 您的应用程序将在main()完成后退出,无需不必要的调用即可显式终止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. 此调用很可能导致您的JUnit在到达assertEquals语句之前停止执行,因为您刚刚告诉VM退出。

Rename the main method, and add a return value, so you can test it. 重命名main方法,并添加返回值,以便进行测试。 Call this new method from main. 从main调用这个新方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM