JUnit test for console input and output

前端 未结 2 490
说谎
说谎 2020-12-21 13:19

I have only one method main. How to check System.out.println() and replace Scanner to input values automatically using JUnit?

P.S. Please, provide some solutions...

2条回答
  •  一整个雨季
    2020-12-21 13:48

    I faced a similar issue and this is what I ended up doing.

    First off, I'd suggest doing as @Jon-Skeet suggests and instead of using the main(String[]) method of the class, create a separate method.

    Then you can have that method take in an InputStream as a parameter and then create a Scanner object within the method that uses the passed InputStream as its source. That way you can pass any InputStream, such as System.in, to the method when it's called (elaboration below).

    package my.package;
    
    import ...;
    
    public class MyClass
    {
        public static void myMethod(InputStream inputStream)
        {
            Scanner inputScanner = new Scanner(inputStream);
    
            // Do stuff with the Scanner such as...
            String input = inputScanner.nextLine();
        
            System.out.println("You inputted " + input);
        }
    }
    

    Now, in your production source code you can call myMethod and pass it System.in as an argument as such, myMethod(System.in);

    And then in your unit tests, you can create mock input values via a ByteArrayInputStream:

    package my.package;
    
    import ...;
    
    public class MyClassTest
    {
        @Test
        void testMyMethod()
        {
            // Simulates a user inputting the string "Mock input" and hitting enter
            assertDoesNotThrow(myMethod(new ByteArrayInputStream("Mock input\n".getBytes())));
        }
    }
    

    And voila, you now have a way to pass your method mock input as well as it being more modular overall.

    I just want to point out without getting too much into it, that when working with System.in, one needs to be careful about closing it and in unit tests when working with input streams, one needs to be careful about reusing a reference to the same InputStream as its state can persist across uses.

提交回复
热议问题