1

I am trying to develop an automatic assignment grading script using JUnit in Java. I am simulating user input by passing in test case inputs (read from a file in the classpath) by changing System.in to a ByteArrayInputStream containing the string data in bytes. I want to be able to run multiple test cases to check all cases and then use the Gradle-built report to mark the assignment submission.

Currently, I have been able to simulate user input to reflect the input provided by the test cases using this link: JUnit: How to simulate System.in testing?. I am also changing System.out to a PrintStream to capture the printed statements from the assignment. My main method spawns a new thread, inside which is the assignment's codes done in, as shown below.

The unit tests perform successfully when I am testing each @Test - annotated case individually. However, when I run all the tests contained in a single Test class, JUnit works successfully in the first @Test -annotated case but fails on the eventual ones, which is somewhat unexpected here. Hopefully the codes below will help to clarify the situation.

My Main method:

public static void main(String ... args) {
    Assignment assignment = new Assignment();
    new Thread(assignment).start();
}

My test class has some @before and @after annotated methods:

@Before
public void setup() {
    systemIn = System.in; // global variable
    systemOut = System.out; // global variable
    output = new ByteArrayOutputStream(); // global variable
    System.setOut(new PrintStream(output));
    assignment = new Assignment();
}
@After
public void conclude() {
    System.setIn(systemIn);
    System.setOut(systemOut);
}

I am reading the corresponding file for each test case input and output, and in the function below, I am setting the test case input.

private void setInput(String data) {
    ByteArrayInputStream input = new ByteArrayInputStream(data.getBytes());
    System.setIn(input);
}

I am running each test case as follows:

@org.junit.Test // 2,3,4 ....for other cases
public void runTestCase1() { 
    testCases(1);
}

The IO class the assignment is using is as follows:

public static String readLine() { // w/o try/catch blocks
    String read = reader.readLine(); // reader -> bufferedReader(new InputStream(System.in))
    return read.trim();
}

Also note that I am using Thread.sleep(50) before invoking the main method so that the input test case is successfully read and loaded in System.in in time for Assignment to execute.

When running all tests together, the first test gives the correct output, i.e. the expected and the actual outputs match. However, for the second case and onward, IO.readline() generates a null pointer exception and hence no output is produced by the assignment. Upon investigation, I discovered that during the second case, System.in is no longer pointing to a ByteArrayInputStream, but rather (the old?) BufferedInputStream. I am confused why this might be happening (probably due to a new thread spawning maybe?) and how do I overcome this problem?

sbsatter
  • 458
  • 2
  • 18

0 Answers0