VOOZH about

URL: https://www.geeksforgeeks.org/advance-java/unit-testing-system-in-for-input-handling-in-junit/

⇱ Unit Testing System.in for Input Handling in JUnit - GeeksforGeeks


  • Courses
  • Tutorials
  • Interview Prep

Unit Testing System.in for Input Handling in JUnit

Last Updated : 23 Jul, 2025

In Java applications, it’s common to read input from System.in for interactive console applications. Unit testing such methods can be challenging because they rely on user input. We can achieve this by redirecting System.in to a ByteArrayInputStream that contains the input we want to simulate.

In this article, we will learn how to perform unit testing of System.in in Java using JUnit.

Maven Dependencies

Include the below JUnit 5 dependencies into the pom.xml file to set up the testing environment.

<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
</dependencies>

Unit Testing of System.in

The purpose of unit testing is to ensure that individual pieces of code, functions or methods, in isolation are correct. Testing becomes more difficult when a method relies on external input such as the user input through System.in. By default, System.in expects users to provide input through the console, but in automated tests, we want to simulate this input programmatically.

The basic idea is to convert System.in to another input stream, such as ByteArrayInputStream, which allows automatic, repeatable hands-free testing. Basic steps include:

  1. Redirecting System.in: Use ByteArrayInputStream to simulate user input during the test.
  2. Restoring System.in: Ensure that System.in is restored to its original state after the test to avoid side effects on other tests.
  3. Writing Assertions: Verify the behavior of the code by checking the output or state after processing the input.

Working of System.in Unit Testing

We can replace System.in with any input stream using the System.setIn(InputStream in) method. For testing purposes, ByteArrayInputStream can be used to simulate the input. After simulating the input, we can execute the method under test and make assertions to verify that the method behaves as expected.

Example:

Create a Method that Reads from System.in

Let’s create a simple Java class, InputReader, with a method that reads user input from System.in and returns it.

public class InputReader {

// This method reads from System.in and returns the input as a String
public String readInput() {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter input: ");
return scanner.nextLine();
}
}

In this class, readInput() reads a line of input from System.in and returns it. Normally, this method would wait for user input, but for testing purposes, we will simulate this input.

Simulating System.in for Testing

To test this method without requiring user interaction, we’ll use ByteArrayInputStream to simulate System.in. By setting System.in to an input stream containing test data, we can automate the input for testing purposes.

Write the JUnit Test Case

Here is a JUnit test for the InputReader class. We will set System.in to a ByteArrayInputStream that contains our simulated user input.

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InputReaderTest {

private final InputStream originalSystemIn = System.in;
private ByteArrayInputStream testIn;

@BeforeEach
public void setUpInput() {
// This method runs before each test to set up the input
}

@AfterEach
public void restoreSystemIn() {
// Restore System.in after each test
System.setIn(originalSystemIn);
}

@Test
public void testReadInput() {
// Simulate user input "Hello World"
String simulatedInput = "Hello World";
testIn = new ByteArrayInputStream(simulatedInput.getBytes());
System.setIn(testIn);

// Invoke the method to be tested
InputReader inputReader = new InputReader();
String input = inputReader.readInput();

// Assert that the method returns the correct result
assertEquals(simulatedInput, input);
}
}

Project Implementation of System.in Unit Testing With JUnit

Step 1: Create a New Maven Project

Create a new Maven project using IntelliJ IDEA. Choose the following options:

  • Name: testing-system-in
  • Build system: Maven

Click on the Create button.

πŸ‘ Project Metadata

Project Structure

After the project creation done, set the folder structure as shown in the below image:

πŸ‘ Project Folder Structure

Step 2: Add the JUnit Dependencies to pom.xml

Open the pom.xml file and add the following JUnit 5 dependencies:

Step 3: Create the UserInput Class

Create a class named UserInput to read a number from the user and return its square:

Step 4: Create the Main Class

Create a main class to execute the program:

Step 5: Create the UserInputTest Class

To test the UserInput class, create the following test class:

Step 6: Run the Application

Once the project is complete, run the Main class. We will see the below output in the console:

πŸ‘ Output

Step 7: Running the Tests

Now, we will run the tests, use the following Maven command in the terminal.

mvn test

Output:

πŸ‘ Test Output

In this article, we demonstrated how to perform unit testing on methods that read from System.in using JUnit.

Conclusion

Simulating System.in in the unit tests is a powerful technique to test the input-dependent methods in the Java. By redirecting the input stream using the ByteArrayInputStream, we can simulate the various user inputs and verify the correctness of the methods. This approach can helps in the automating tests and ensuring the code quality.

Comment
Article Tags:
Article Tags:

Explore