NsTest 클래스에 메서드를 파악해보자.
ApplicationTest
테스트가 상속
받고 있는 NsTest
가 뭘까? 왜 추상 클래스일까?
진행되는 전체적인 로직의 동작 원리가 궁금해졌다.
PrintStream과 OutputStream 두개가 있었다. 아무래도 입출력을 관리하기 위한 필드일 듯
하다.
이 부분에서 System.out 가 선언된 것을 보니 print, println 에 관한 작업을 할 것 같다.
- print, println, printf와 같은 메소드들을 오버 로딩(over loading)하여 제공한다.
java.lang.Object
- java.io.OutputStream
- java.io.FilterOutputStream
- java.io.PrintStream
데이터를 저장
해두었다가, 한꺼번에 출력
을 위한 저장소 개념으로 사용 되는 듯하다.
이 메서드는 처음 보게 되어 안에 내부를 살펴봤는데 콘솔에 관련한 동작을 제어하는 듯하다.
클래스가 생성되면 초기화해주는 메서드로,
System.out.아래 친구들
중 콘솔에 출력 작업
이 되는 데이터 전부
를 captor 에 저장하게끔
설정했다.
여기에 print, println 도 포함된다.
protected final void init() {
standardOut = System.out;
captor = new ByteArrayOutputStream();
System.setOut(new PrintStream(captor));
}
실제 프로그램이 수행된 뒤, 입력 역할을 수행하기 위한 메서드
이다.
입력 내용
을 매개변수로 받고, 그 값을 바이트코드로 변환
하고 개행으로 입력 간 사이를 나눈다.
그리고 그값을 setIn
하면 시스템 상 입력을 위한 준비가 끝난다.
private void command(final String... args) {
final byte[] buf = String.join("\n", args).getBytes();
System.setIn(new ByteArrayInputStream(buf));
}
프로그램 실행 동작을 수행
protected final void run(final String... args) {
command(args);
runMain();
}
System.out ~ 로 출력된 모든 데이터
를 captor 에 저장해두었던 것을 toString 으로 변경하여 리턴
한다.
protected final String output() {
return captor.toString().trim();
}
output 으로 얻게 된 데이터를 출력한다.
protected final void printOutput() {
System.setOut(standardOut);
System.out.println(output());
}
내부를 살펴보면 runMain 만 abstract 메서드이다.
내가 유추해본 추상화 클래스 인 이유는 실제 동작 내용은 변화 가능성이 낮기 때문에 고정 시켜 두고,
main 은 변경 가능성이 높아서 NsTest 를 상속받아 사용하는 클래스에서 구현하도록 해놓기 위해서가 아닌가 싶다.
콘솔에 출력되는 문자들을 어떻게 contains 할 수 있지? 궁금했는데
그 부분이 해소되었고, 이런 로직을 깔끔하게 라이브러리 화 한 nextstep 분들이 대단하다고 느꼈다.
테스트 코드를 위한 클래스를 따로 생성하고, 테스트 로직을 간결하게 만든 것도 대단하고,
기능, 클래스를 분리하는게 이런거구나 알 수 있었다. 원하는 동작을 수행시킬 수 있는 능력이 부럽다.
그리고 네이밍도 기가 막히는 것 같다. ㅋㅋㅋㅋㅋㅋㅋㅋ 감탄의 연속 ...
내 코드도 언젠가는 유연해지길 기대한다.