Recently I started studying competitive programming. It is troublesome to input each time when checking the operation locally. I want to do it with JUnit.
Qiita --Push standard input in JUnit Kenkoba's Diary-Stealing Standard I / O Nyoki Nyoki Blog --Let's replace System.out
You can change the output destination and input destination from standard output and input with setOut and setIn of the System class.
You can define and set a class that inherits PrintStream for Out and ʻInputStream` for In.
Create input class and output class.
StandardInputStream.java
import java.io.InputStream;
public class StandardInputStream extends InputStream {
    private StringBuilder sb = new StringBuilder();
    private String lf = System.getProperty("line.separator");
    /**
     *Enter the character string. Line breaks are done automatically
     * @param str input string
     */
    public void inputln(String str){
        sb.append(str).append(lf);
    }
    @Override
    public int read() {
        if (sb.length() == 0) return -1;
        int result = sb.charAt(0);
        sb.deleteCharAt(0);
        return result;
    }
}
StandardOutputStream.java
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.StringReader;
public class StandardOutputStream extends PrintStream {
    private BufferedReader br = new BufferedReader(new StringReader(""));
    public StandardOutputStream() {
        super(new ByteArrayOutputStream());
    }
    /**
     *Read one line of string
     * @return Characters that do not contain newlines. Null for termination
     */
    public String readLine() {
        String line = "";
        try {
            if ((line = br.readLine()) != null) return line;
            br = new BufferedReader(new StringReader(out.toString()));
            ((ByteArrayOutputStream) out).reset();
            return br.readLine();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
The code to be tested is borrowed from atcoder. PracticeA - Welcome to AtCoder
** Problem ** Given the integers a, b, c and the string s. Display the calculation result of a + b + c and the character string s side by side.
** Input **
a b c s
#### **`WelcomeToAtCoder.java`**
```java
import java.util.Scanner;
public class WelcomeToAtCoder {
    public static void main(String[] args) {
        try (Scanner sc = new Scanner(System.in)) {
            int r = sc.nextInt();
            r += sc.nextInt();
            r += sc.nextInt();
            String s = sc.next();
            System.out.println(r + " " + s);
        }
    }
}
WelcomeToAtCoderTest.java
import WelcomeToAtCoder;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import util.io.StandardInputStream;
import util.io.StandardOutputStream;
import static org.hamcrest.CoreMatchers.is;
public class WelcomeToAtCoderTest {
    private StandardInputStream in = new StandardInputStream();
    private StandardOutputStream out = new StandardOutputStream();
    @Before
    public void before() {
        System.setIn(in);
        System.setOut(out);
    }
    @After
    public void after() {
        System.setIn(null);
        System.setOut(null);
    }
    @Test
    public void main01() {
        in.inputln("1");
        in.inputln("2 3");
        in.inputln("hoge");
        WelcomeToAtCoder.main(null);
        Assert.assertThat(out.readLine(), is("6 hoge"));
    }
}
I / O is switched and tested in advance.
It's easy to write test cases, so I think it's easier to implement. Not limited to this, I decided to write the test properly. I want to study TDD. ~~ JUnit touched after a long time ~~
Recommended Posts