如何单元测试java main方法?

时间:2016-01-04 22:53:47

标签: java junit4

我有一个类,我必须通过它的main方法传递2个参数,如果传递少于2个参数,它会显示一个系统错误消息。我在这里为main方法编写了一个单元测试,当我运行测试时,它停止在“running”(显示既不通过也不失败)。请建议。

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

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

4 个答案:

答案 0 :(得分:2)

以下内容如何:

class TestingSecurityManager extends SecurityManager {
  @Override public void checkExit(int status) {
    throw new SecurityException();
  }
}

然后在你的测试中...

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

答案 1 :(得分:2)

我终于能够编写单元测试,如下所示。我只测试了该方法是否符合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));
    }
}

答案 2 :(得分:0)

删除System.exit(1)调用,您不需要它。您的应用程序将在main()完成后退出,无需不必要的调用即可显式终止VM。此调用很可能导致JUnit在到达assertEquals语句之前停止执行,因为您刚刚告诉VM退出。

答案 3 :(得分:0)

重命名main方法,并添加返回值,以便进行测试。从main调用这个新方法。