입력 받는 기능을 테스트해야 하는 경우
테스트 실행 후 read-only 상태인 콘솔을 조작하지 못해 무한 대기하거나, 값이 할당되지 않았기 때문에 NullPointerException을 맞이하여 프로덕션 코드를 진행하지 못하는 문제가 있었습니다.
public String putReadLine() {
System.out.println(PUT.render());
return Console.readLine();
}
@Test
public void 숫자_입력_받기(){
String expect = "123";
String actual = inputView.putReadLine();
assertEquals(expect, actual);
}
}
단위 테스트를 진행하면서 프로덕션 코드를 개선해나기 위해 노력해보았습니다.
System 클래스의 setIn()이라는 기능이 있습니다.
public static void setIn(InputStream in) {
checkIO();
setIn0(in);
}
This abstract class is the superclass of all classes representing an input stream of bytes.
Applications that need to define a subclass of InputStream must always provide a method that returns the next byte of input.
시작 시간:
1.0
관련 주제:
BufferedInputStream, ByteArrayInputStream, DataInputStream, FilterInputStream, read(), OutputStream, PushbackInputStream
작성자:
Arthur van Hoff
public class Console {
private static Scanner scanner;
private Console() {
}
public static String readLine() {
return getInstance().nextLine();
}
문자열 입력 받는 기능을 구현해야 하는 상황
BufferedInputStream, DataInputStream은 String으로 변환하는데 감 잡기가 힘들었습니다.
getBytes()를 사용하면 문자열을 바이트 형태로 인코딩하여 배열로 저장할 수 있다고 합니다.
/** * Encodes this {@code String} into a sequence of bytes using the * platform's default charset, storing the result into a new byte array. * * <p> The behavior of this method when this string cannot be encoded in * the default charset is unspecified. The {@link * java.nio.charset.CharsetEncoder} class should be used when more control * over the encoding process is required. * * @return The resultant byte array * * @since 1.1 */ public byte[] getBytes() { return StringCoding.encode(coder(), value); }
ByteArrayInputStream 클래스를 구현체로 선택했습니다.
혹시 모를 변경을 위해 정적 팩토리를 참고하여 반환 객체를 자유롭게 선택할 수 있는 구조를 만들었습니다.
public static InputStream setReadLine(String readLine) {
return new ByteArrayInputStream(readLine.getBytes());
}
@Test
public void 숫자_입력_받기(){
InputStream readLine = setReadLine("926");
System.setIn(readLine);
String expect = "926";
String actual = inputView.putReadLine();
assertEquals(expect, actual);
}
}
private static Scanner getInstance() {
if (Objects.isNull(scanner) || isClosed()) {
scanner = new Scanner(System.in);
}
return scanner;
}
new Scanner(System.in)에 들어갔어야 할 코드가
System.setIn(setReadLine)으로 대체되었음을 유추할 수 있는 것 같습니다.
내가 과거에 쓴 글 내가봐도 이해못하겠음
ㅅㅂ