2014-02-07 51 views
1

我需要JUnit测试现有的代码由输出(在的System.out)测试输出与主到Console.ReadLine()涉及

public static void main(String args[]) 
{ 
    Console console = System.console(); 
    String str = console.readLine(); 
    System.out.println("halo"+str); 

} 

由于到Console.ReadLine正在等待用户的输入,我发现它会停在console.readline(),因此阻止我获取输出。

有没有办法做到这一点?使用Mockito或其他软件可以做到这一点吗?

回答

2

这几乎是不可能的测试代码与System.console()工作,因为你永远System.console()在测试中retuns null。另外Console是没有公共构造函数的最终类。

我推荐与Console的作者和读者一起工作,并测试与编写者和读者一起工作的代码。

public static void main(String args[]) { 
    Console console = System.console(); 
    BufferedReader reader = new BufferedReader(console.reader()); 
    main2(reader, console.writer(), args); 
} 

static void main2(BufferedReader reader, Writer writer, String args[] { 
    String str = reader.readline(); 
    System.out.println("halo"+str); 
} 

输出到System.out可以与System Rules库的StandardOutputStreamLog规则进行测试。但在你的代码中写入Console的作者而不是System.out要容易得多。

0

main方法不适合单元测试。它只是一个应用程序的入口点。可能你需要重构你的类来进行某种依赖注入。例如:

public class Something { 

    private final LinesProvider linesProvider; 

    public Something(LinesProvider linesProvider) { 
     this.linesProvider = linesProvider; 
    } 

    public void sayHello() { 
     String str = linesProvider.readLine(); 
     System.out.println("halo "+str); 
    } 

    public static void main(String args[]) { 
     new Something(new LinesProvider() { 
      private final Console console = System.console(); 
      @Override 
      public String readLine() { 
       return console.readLine(); 
       } 
     }).sayHello(); 
    } 
} 

interface LinesProvider { 
    String readLine(); 
} 

然后,您可以测试系统输出如下所示,但这不是一个好习惯。相反,尝试从程序中分离逻辑I/O逻辑:

public class TestSomething { 

    private ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 
    private PrintStream printStream = new PrintStream(outputStream, true); 

    @Before 
    public void setUp() { 
     System.setOut(printStream); 
    } 

    @Test 
    public void test() { 
     new Something(new LinesProvider() { 
      @Override 
      public String readLine() { 
       return "Vasya"; 
      } 
     }).sayHello(); 

     assertEquals("halo Vasya" + System.getProperty("line.separator"), new String(outputStream.toByteArray())); 
    } 
} 
0

下面的测试将工作,使用JMockit嘲讽API:

@Test 
public void testMyApp(@Mocked final Console console) 
{ 
    new NonStrictExpectations(System.class) {{ 
     System.console(); result = console; 
     console.readLine(); result = " test"; 
    }}; 

    OutputStream output = new ByteArrayOutputStream(); 
    System.setOut(new PrintStream(output)); 

    MyApp.main(new String[0]); 

    String lineSep = System.getProperty("line.separator"); 
    assertEquals("halo test" + lineSep, output.toString()); 
}