새소식

Java

[spring] 스프링부트에서 테스트!

  • -
728x90
Spring Boot Slice Test

 

Spring Boot 를 공부하다 보니 여러가지 테스트를 진행하는 과정에서 통합테스트 나 단위테스트 와 같은 단어들이 등장했다. 테스트의 중요성을 느끼고 기능이 완성될 때마다 충분한 테스트를 거치자고 다짐하기도 했고, 의미를 정확히 모르고 사용하는 것은 무의미하다 생각하여 이번 기회를 통해 정리해보고자 한다!

 

 통합 테스트 (Integration Test) 란 ?

한마디로 여러 컴포넌트 간의 상호 작용을 통합적으로 테스트한다는 의미이다. 주로 Spring 의 @SpringBootTest 어노테이션을 사용하여 애플리케이션 컨텍스트를 로드하고, 실제 Bean 들과 상호작용하면서 애플리케이션의 통합을 확인한다.

애플리케이션의 설정과 모든 Bean을 로드하기 때문에 운영환경과 가장 유사한 테스트가 가능하고 전체적인 플로우를 쉽게 테스트할 수 있다는 장점이 있지만, 그만큼 시간이 오래걸리고 무거우며 테스트 단위가 크기 때문에 디버깅이 어렵다는 단점이 존재한다.

 

통합테스트 작성 단계

1. 애플리케이션 컨텍스트 로드

: @SpringBootTest 어노테이션을 사용하여 실제 애플리케이션 컨텍스트를 로드한다.

import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class MyIntegrationTest {
    // 통합 테스트 코드 작성
}

 

2. 테스트 실행

: @Test 어노테이션을 사용하여 테스트 메소드를 정의한다.

import org.junit.jupiter.api.Test;

@SpringBootTest
class MyIntegrationTest {

    @Test
    void testSomething() {
        // 통합 테스트 코드 작성
    }
}

 

3. 자동 주입 및 상호 작용

: @Autowired 어노테이션을 사용하여 테스트에서 사용할 빈을 주입한다.

주로 MockMvc, TestRestRemplate 등을 사용하여 HTTP 요청을 수행하거나, 실제 서비스 메소드를 호출하고 결과를 검증한다.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest
@AutoConfigureMockMvc
class MyControllerIntegrationTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void testGetMessage() throws Exception {
        mockMvc.perform(get("/api/message"))
               .andExpect(status().isOk());
    }
}

 

* 테스트 데이터베이스 구성

: 통합 테스트에서 종종 실제 데이터베이스와 상호 작용해야 할 경우가 있다. 그러한 경우에 테스트 전용 데이터베이스를 사용한다.

import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.TestPropertySource;

@DataJpaTest
@TestPropertySource(properties = {
    "spring.datasource.url=jdbc:h2:mem:testdb"
})
class MyRepositoryIntegrationTest {
    // ...
}

 

@SpringBootTest

- 스프링부트는 @SpringBootTest 어노테이션을 통해 스프링부트 애플리케이션 테스트에 필요한 대부분의 의존성을 제공.

- 통합 테스트를 제공하는 기본적인 스프링 부트 테스트 어노테이션.

- @SpringBootTest 어노테이션 사용시 Junit 버전에 따라 유의사항이 존재한다.

  • Junit4 : @RunWith(SpringRunner.class) 와 함께 사용.
  • Junit5 : 따로 명시할 필요 없음.

@SpringBootTest의 옵션

1. properties

1.1 프로퍼티를 {key = value} 형식으로 직접 추가가 가능하다.

@SpringBootTest(properties = {"name=yonghwan"})
public class SampleSpringBootTest {
    @Value("${name}")
    private String name;

    @Test
    public void testName(){
        assertThat(name).isEqualTo("yonghwan");
    }
}

 

1.2 프로퍼티의 키값으로 “spring.config.location”으로 설정하고 값으로 외부 파일을 설정하여 외부파일의 프로퍼티를 가져오는 것이 가능함

src/test/test.yml

yonghwan:
  name: YongHwan
  age: 20

 

@SpringBootTest 애노테이션의 properties 옵션을 이용하여 외부 파일을 다음과 같이 불러온다

@SpringBootTest(properties = {"spring.config.location = classpath:test.yml"})
public class SampleSpringBootTest {
    @Value("${yonghwan.age}")
    private int age;

    @Test
    public void testAge(){
        assertThat(age).isEqualTo(20);
    }
}

webEnvironment

- 웹 테스트 환경 구성이 가능하다.

- webEnvironment 파라미터를 이용하여 손쉽게 웹 테스트 환경을 선택할 수 있다.

- 웹 테스트 환경 종류

  • Mock
  • RANDOM_PORT
  • DEFINED_PORT
  • NONE

Mock

- 실제 객체를 만들기엔 비용과 시간이 많이 들거나 의존성이 길게 걸쳐져 있어 제대로 구현하기 어려운 경우, 가짜 객체를 만 들어 사용한다.

- WebApplicationContext를 불러오며 내장된 서블릿 컨테이너가 아닌 Mock 서블릿을 제공한다.

- @SpringBootTest 애노테이션의 webEnvironment 옵션의 기본값

- @AutoConfigureMockMvc 애노테이션을 함께 사용하여 MockMvc를 사용한 테스트 진행 가능하다.

  • MockMvc는 브라우저에서 요청과 응답을 의미하는 객체. Controller 테스트 사용을 용이하게 해주는 라이브러리
  • @AutoConfigureMockMvc 애노테이션은 Mock 테스트시 필요한 의존성을 제공한다.
@Autowired
MockMvc mockMvc;

 

RANDOM_PORT

- 내장된 WebApplicationContext를 불러오며 실제 서블릿 환경을 구성함

- 임의의 포트를 지정함

- 실제 서블릿 컨테이너를 사용하기 때문에 TestRestTemplate 사용

 

DEFINED_PORT

- RANDOM_PORT와 동일하게 실제 서블릿 환경을 구성하지만, 포트는 애플리케이션 프로퍼티에서 지정한 포트를 지정한다.

- 실제 서블릿 컨테이너를 사용하기 때문에 TestRestTemplate 사용

 

NONE

- 기본적인 ApplicationContext를 불러옴

 

TestRestTemplate란 무엇인가?

- 통합 테스트에 적합한 RestTemplate의 대안

- 4xx 및 5xx는 예외가 발생하지 않음. 대신 Response 엔티티 및 상태 코드를 통해 탐지될 수 있음

- 기본 인증 헤더가 선택적으로 포함될 수 있음 Apache Http Client 4.3.2 이상이 사용 가능한 경우 권장 클라이언트로 사용되며 기본적으로 쿠키 및 리다이렉션을 무시하도록 구성됨

- 주입 문제를 방지하기 위해 이 클래스는 의도적으로 RestTemplate를 확장하지 않음

  • 기본 RestTemplate에 접근 권한이 필요한 경우 getRestTemplate()를 사용함
@Autowired
TestRestTemplate testRestTemplate;

 

@MockBean

- Mock 객체를 빈(Bean)으로써 등록할 수 있음

- @MockBean 애노테이션 적용시 스프링의 ApplicationContext는 Mock 객체를 빈으로 등록하며, @MockBean으로 선언된 객체와 같은 이름과 타입으로 이미 빈이 등록되어 있다면 해당 빈은 선언한 @MockBean으로 대체된다.

Root 개념을 구현할 때 유용한다.


 

728x90

'Java' 카테고리의 다른 글

[Java] JVM 이란  (0) 2024.04.23
[Spring] Redis 로 성능개선 with Spring Boot  (0) 2024.02.25
[Java] Spring Retry  (0) 2024.02.21
[Java] 비트 연산  (0) 2024.02.20
[Spring] Spock으로 테스트 코드를!  (0) 2024.02.18
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.