티스토리 뷰

개요

  • 보통 로그는 그냥 남기기만 하고 테스트는 많이 하지 않는다.
  • 하지만 로그의 레벨이나 내용에 따라 뭔가를 처리해야하면 로그도 테스트해야한다.
  • 파일로 출력하는 로그는 파일 읽어들여서 테스트하면되지만,
    콘솔에 출력하는 로그라면 어떻게 그 내용을 가져올 지 감이 안 올 수도 있겠다.
  • 검색하면서 찾아낸 방법과 실제로 사용했던 방법에 대해 소개한다.

 

로그Appender를 지정하는 방법

  • 평소에 많은 도움을 받고 있는 Baeldung에서 소개하는 방법이다.
  • 로그를 콘솔이 아닌 메모리 어펜더로 남기는 방법이다.
  • 이 내용은 보기만 하고 실제로는 실험도 해보지 않았다.
  • 이유는 파일 어펜더랑 뭐가 다르지? 파일 어펜더가 로그도 남겨놓기 편하고 더 좋은데?였다.
  • 링크: https://www.baeldung.com/junit-asserting-logs

 

콘솔의 출력 스트림을 바꾸는 방법

  • 콘솔의 출력 방향을 바꾸는 방법이다.
  • 콘솔 출력을 어떻게 하는지를 떠올린다면 찾을 수 있는 방법이다.
  • 콘솔 출력을 할 때는 보면 아래와 같은 코드를 많이 쓰는데 out이 무엇인가 살펴보면 PrintStream이다.
System.out.println("ABCDEFG");

  • final로 되어있지만 System.setOut메소드로 변경이 가능하다.
  • 각 단계에 대해서는 실제코드에서 설명하도록 한다.

 

실제코드

package com.example;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;

import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.is;

public class LogTest {
    public static class Service {
        Logger logger = LoggerFactory.getLogger(Service.class);

        public void run(int i) {
            logger.info("test" + i);
        }
    }

    private final Service service = new Service();

    @Test
    public void logTest() {
        // 스트림을 바꾸기 전의 출력
        System.out.println("console output 1");

        // 테스트 끝나고 원래대로 돌리기 위해 별도의 변수에 기존 스트림을 저장해둔다.
        var originalOut = System.out;
        
        // 원하는 스트림을 만든다. 나중에 String으로 만들 것이기 때문에 ByteArrayOutputStream을 이용하였다.
        var logStream = new ByteArrayOutputStream();

        // 콘솔의 스트림을 바꾼다.
        System.setOut(new PrintStream(logStream));

        // 바뀐 콘솔 스트림으로 출력 시작
        System.out.println("console output 2");
        this.service.run(1);
        this.service.run(2);
        this.service.run(3);
        System.out.println("console output 3");

        // 스트림의 내용을 스트링으로 바꾼다.
        var logString = logStream.toString();

        // 개행문자로 각 로그라인을 나눈다.
        var logLines = logString.split("\r\n");
        
        // 로그의 갯수부터 테스트한다.
        assertThat(logLines.length, is(5));
        var lineCnt = 0;
        
        // 각 로그의 내용을 테스트한다. 가장 앞에는 시간이기 때문에 '[main]'부터의 로그 메시지를 테스트한다.
        assertThat(logLines[lineCnt++], endsWith("console output 2"));
        assertThat(logLines[lineCnt++], endsWith(" [main] INFO com.example.LogTest$Service -- test1"));
        assertThat(logLines[lineCnt++], endsWith(" [main] INFO com.example.LogTest$Service -- test2"));
        assertThat(logLines[lineCnt++], endsWith(" [main] INFO com.example.LogTest$Service -- test3"));
        assertThat(logLines[lineCnt++], endsWith("console output 3"));

        // 원래 스트림으로 돌린다.
        System.setOut(originalOut);
        
        // 이제부터는 원래 콘솔의 스트림으로 출력한다.
        System.out.println("console output 4");
        System.out.println("Break");
    }
}

디버그모드에서의 각종 값들

 

테스트 실행시의 콘솔 출력