[Java] 콘솔창 출력 테스트하기

유콩·2022년 3월 31일

결과값을 확인해야 하는 메서드에서 값이 바로 출력되어 출력값을 테스트하는 방법을 찾아보았다.

stream

배열이나 컬렉션에 담긴 데이터를 관리하기 위한 Stream 객체를 의미하는 것이 아니다. 여기에서 stream 이란 데이터를 운반하는 데 사용되는 연결 통로 이다. 입출력은 컴퓨터 내부 또는 외부의 장치와 프로그램 간의 데이터를 주고 받는 것을 의미한다. stream 은 단방향 통신만 지원하기 때문에 자바에서는 입력을 지원하기 위한 InputStream 과 출력을 지원하기 위한 OutputStream 으로 객체를 분리하여 관리한다.

바이트기반 스트림 - InputStream 과 OutputStream

스트림은 바이트 단위로 데이터를 전송한다. InputStreamOutputStream 은 추상 클래스로 입출력에 관한 기능을 추상메서드로 정의해두었다. 각자 입출력 대상에 따라 상속받은 클래스를 사용하면 된다. 바이트기반 스트림 외에 보조스트림, 문자기반 스트림 등이 있다.

입력스트림출력스트림입출력 대상의 종류
FileInputStreamFileOutputStream파일
ByteArrayInputStreamByteArrayOutputStream메모리(byte배열)
PipedInputStreamPipedOutputStream프로세스(프로세스 간 통신)
AudioInputStreamAudioOutputStream오디오장치

나는 콘솔창에 출력되는 값을 확인하고 싶었기 때문에 ByteArrayOutputStream 클래스를 사용하였다.

System.setOut

출력하려는 값을 OutputStream 객체에 저장하기 위해 기본적으로 설정되어 있는 System.out 의 값을 내가 사용하고 싶은 타입의 객체(ByteArrayOutputStream)로 변경하였다.

private static ByteArrayOutputStream outputMessage = new ByteArrayOutputStream();
System.setOut(new PrintStream(outputMessage));

System 의 out 은 PrintStream 타입이기 때문에 PrintStream 객체를 생성한 값으로 지정하였다.

테스트 종료 후 정상적인 콘솔창 출력을 위해서 다시 되돌려놓는 과정이 필요하다.

System.setOut(System.out);

예시코드

우아한테크코스에서 진행중인 체스 미션에서 출력된 점수가 올바른지 확인하는 테스트 코드를 가져왔다.

package chess.domain.board;

import static org.junit.jupiter.api.Assertions.*;

class StatusTest {

    private static ByteArrayOutputStream outputMessage;

    @BeforeEach
    void setUpStreams() {
        outputMessage = new ByteArrayOutputStream(); // OutputStream 생성
        System.setOut(new PrintStream(outputMessage)); // 생성한 OutputStream 으로 설정
    }

    @AfterEach
    void restoresStreams() {
        System.setOut(System.out); // 원상복귀
    }

    @Test
    @DisplayName("게임 점수 계산")
    void showStatus() {
        Map<Position, Piece> pieces = new HashMap<>();
        pieces.put(Position.from("a1"), new Queen(Color.WHITE));
        pieces.put(Position.from("a2"), new Rook(Color.BLACK));

        Board board = new Board(() -> pieces);

        Status status = new Status(board);
        status.show(Output::printScore);
        assertEquals("검은색의 점수는 5.0점 입니다.\n흰색의 점수는 9.0점 입니다.\n", outputMessage.toString()); // 버퍼에 저장된 값을 가져와 비교한다
    }

    @Test
    @DisplayName("폰이 같은 x 에 존재할 경우의 게임 점수 계산")
    void showStatusPawnScore0_5() {
        Map<Position, Piece> pieces = new HashMap<>();
        pieces.put(Position.from("a1"), new Pawn(Color.WHITE));
        pieces.put(Position.from("a2"), new Pawn(Color.WHITE));
        pieces.put(Position.from("a3"), new Pawn(Color.BLACK));

        Board board = new Board(() -> pieces);

        Status status = new Status(board);
        status.show(Output::printScore);
        assertEquals("검은색의 점수는 1.0점 입니다.\n흰색의 점수는 1.0점 입니다.\n", outputMessage.toString()); // 버퍼에 저장된 값을 가져와 비교한다
    }
}

ByteArrayOutputStream 의 toString() 을 이용해 버퍼에 저장된 바이트 값을 String 으로 반환한다. 반환된 값이 내가 예상한 값과 일치하는지 확인하여 테스트를 하였다.

참고

0개의 댓글