Programming/Spring Boot

로깅, 테스트, Devtools (스프링 부트 활용 - 4)

흠냐아뤼 2020. 3. 9. 20:01
728x90

 

1. 로깅

- 로깅 퍼사드 vs 로거

Commons Logging, SLF4j / JUL, Log4J2, Logback

 

로깅 퍼사드는 실제 로깅을 하는 것이 아니라 로거 기능을 추상화한 인터페이스임

로깅 퍼사드의 장점 : 로깅 퍼사드 밑의 로거를 바꾸어 낄 수 있음

-> 주로 프레임워크는 퍼사드를 이용해 개발함

만약 어떤 프레임워크에서 특정 로거를 쓴다면, 해당 프레임워크를 사용하는 모든 어플리케이션은 해당 로거를 사용해야 함

 

 

기존에는 콘솔 출력만 하는데, 다음 설정으로 로그 파일 저장 가능

// 둘 중 하나만 설정
logging.path=logs	// 디렉토리 설정 
logging.file=logfile	// 파일 설정

로그 파일은 10MB 마다 롤링이 되고 나머지는 아카이브가 됨.

 

- 로그로 남기기

private Logger logger = LoggerFactory.getLogger(SampleRunner.class);
logger.debug("Message");

 

 

2. 테스트

spring-boot-starter-test 의존성 추가

 

- @SpringBootTest (통합 테스트)

@RunWith(SpringRunner.class) 랑 같이 사용해야 함

@SpringBootTest 는 @SpringBootApplication으로 찾아가서 component-scan을 해서 빈으로 등록시키고,

@MockBean은 다시 목 빈 객체를 만들어 기존 빈을 대체시킴

-> 아주 큰 통합된 테스트임!

 

- WebEnvironment.MOCK

내장 톰켓을 구동하지 않고, 구동하는 것처럼 테스트

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@AutoConfigureMockMvc
public class SampleControllerTest {

    @Autowired
    MockMvc mockMvc;

    @Test
    public void hello() throws Exception {
        mockMvc.perform(get("/hello"))
                .andExpect(status().isOk())
                .andExpect(content().string("hello hongchan"))
                .andDo(print());
    }

}

 

- WebEnvironment.RANDOM_PORT

내장 톰켓 사용하여 테스트

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class SampleControllerTest {

    @Autowired
    TestRestTemplate testRestTemplate;

    @Test
    public void hello() {
        String object = testRestTemplate.getForObject("/hello", String.class);
        assertThat(object).isEqualTo("hello hongchan");
    }

}

 

- @MockBean

ApplicationContext에 들어있는 빈을 Mock으로 만든 객체로 교체한다.

모든 @Test 마다 자동으로 리셋

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class SampleControllerTest {

    @Autowired
    TestRestTemplate testRestTemplate;

	// Controller가 사용하는 service 대신 mock Service로 대체하여 테스트를 사용
    // 끊어낼 수 있어서 서비스 단 까지 가지 않아도 됨
    @MockBean
    SampleService mockSampleService;

    @Test
    public void hello() {
        when(mockSampleService.getName()).thenReturn("jiyun");

        String object = testRestTemplate.getForObject("/hello", String.class);
        assertThat(object).isEqualTo("hello jiyun");
    }

}

 

- WebTestClient

위와 달리 비동기적으로 실행됨 (성능 향상)

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class SampleControllerTest {

    // webflux 의존성 추가해야 사용 가능
    // TestRestTemplate 과 달리 비동기적으로 작동함
    // 완료하면 요청이와서 콜백이 실행됨
    // API 도 비교적 사용하기 좋음, 이것 때문에 의존성 추가할 정도 (추천)
    @Autowired
    WebTestClient webTestClient;

    @MockBean
    SampleService sampleService;

    @Test
    public void hello() {
        when(sampleService.getName()).thenReturn("jiyun");

        webTestClient.get().uri("/hello").exchange()
                .expectStatus().isOk()
                .expectBody(String.class).isEqualTo("hello jiyun");
    }

}

 

- 슬라이스 테스트 

레이어 별로 빈들이 등록되기 때문에 각 레이어 별로 테스트를 진행할 수 있음 <-> @SpringBootTest (통합테스트)

@JsonTest

@WebMvcTest (컨트롤러 하나만 테스트할 때, 위의 예제에서 Service는 빈으로 등록 안됨! @MockBean 사용해야 함)

@WebFluxTest

@DataJpaTest

 

 

- @OutputCapture

특정 로그 메시지가 출력이 되는지 테스트 코드로 확인하고 싶을 때 유용함

 

 

3. Spring-Boot-Devtools

완벽하지는 않아서 잘 쓰지는 않음 

 

- 캐시 설정을 개발 환경에 맞게 변경 (꺼줌)

- 코드를 변경하고 빌드하면 빠르게 재시작해줌

 

 

 

 

 

인프런 백기선님 '스프링 부트’  강의를 듣고 정리한 내용입니다.
728x90