Spring 단위 테스트

테스트 종류

Spring는 다양한 시나리오 별로, 여러 개의 테스트를 수행할 수 있는 기능을 제공한다. 테스트는 다음과 같다.

SpringBootTest

전체 애플리케이션 컨텍스트를 로드하여 통합 테스트를 수행한다.

@SpringBootTest는 Spring Boot 애플리케이션을 완전하게 로드하여 실제 애플리케이션과 같은 환경에서 테스트를 수행한다. 데이터베이스, 메시지 큐, REST API 등 모든 컴포넌트를 포함한 전체 애플리케이션을 테스트하고자 할 때 유용하다.

 

사용 예)

@SpringBootTest private class Test() {
@Autowired private MyService myService;
@Test void testServiceMethod() {
}
}

 

DataJpaTest

JPA 리포지토리 관련 테스트를 위한 어노테이션이다.

JPA와 관련된 빈만 로드하고, 데이터베이스와 관련된 테스트를 진행한다.

사용 예)

@DataJpaTest public class Test {
@Autowired private UserRepository userRepository;
@Test void test() {
User user = new User(“John”, “john@example.com“);
userRepository.save(user);

User foundUser = userRepository.findById(user.getId()).orElse(null);
assertThat(foundUser).isNotNull;
}
}

 

WebMvcTest

웹 계층(컨트롤러, HTTP 요청/응답)만 테스트를 진행하는 어노테이션이다.

Spring MVC의 웹 컴포넌트만 로드하여 컨트롤러 테스트에 사용한다.

사용 예)

@WebMvcTest(Controller.class) public class Test {
@Autowired private MockMvc mockMvc;
@Test void testController() throws Exception {
mockMvc.perform(get(“/api/endpoint”))
.andExpect(status().isOk())
.andExpect(jsonPath(“$.name”).value(“John”));
}
}

 

MockBean

목적: 테스트에서 빈을 mock으로 대체할 때 사용한다.

설명: 실제 빈 대신 mock 객체를 주입하여 테스트에서 의존성을 격리할 때 사용한다.

사용 예)

@WebMvcTest(Controller.class) public class Test {
@MockBean private MockService mockService;
@Test void testController() throws Exception {

 

Mockito.when(mockService.getUser()).thenReturn(new User(“John”));

mockMvc.perform(get(“/api/endpoint”))
.andExpect(status().isOk())
.andExpect(jsonPath(“$.name”).value(“John”));
}
}

 

TestConfiguration

테스트 환경에서만 사용하는 설정을 정의할 때 사용한다.

테스트 전용 설정을 작성할 수 있는 어노테이션이다.

사용 예)

@TestConfiguration static class MyTestConfig {
@Bean public MyService myService() {
return new MyServiceImpl();
}
}

 

JsonTest

JSON 직렬화/역직렬화 테스트.

객체를 JSON으로 직렬화하거나 JSON을 객체로 역직렬화하는 로직을 테스트할 때 사용.

사용 예)

@JsonTest public class UserJsonTest {
@Autowired private ObjectMapper objectMapper;

@Test void testSerialization() throws JsonProcessingException {
User user = new User(“John”, “john@example.com”);
String json = objectMapper.writeValueAsString(user);
assertThat(json).contains(“John”);
}
}

 

ConfigurationPropertiesTest

@ConfigurationProperties로 설정된 프로퍼티 클래스 테스트

프로퍼티 값이 제대로 바인딩되는지 테스트.

사용 예)

@ConfigurationPropertiesTest public class MyConfigPropertiesTest {
@Autowired private MyConfigProperties properties;

@Test void testProperties() {
assertThat(properties.getName()).isEqualTo(“John”);
}
}

 

ActiveProfiles

특정 프로파일을 활성화하여 테스트 환경 설정.

설정 파일이나 환경을 테스트용으로 변경하고 싶을 때 사용.

사용 예)

@SpringBootTest
@ActiveProfiles(“test”)
public class MyServiceTest {
@Autowired
private MyService myService;

@Test
void testService() {
// ‘test’ 프로파일 환경에서 테스트
}
}

 

기타 문제 해결

Spring Application 없이 DataJpaTest 설정 시 Configuration 관련 에러

DataJpaTest는, JPA로 설정된 데이터들만 불러오는 것이 아니라, 어플리케이션을 초기화 하고, JPA와 관련 없는 Bean들을 무시하고 로딩되는 테스트이다. 따라서, Application 설정 파일이 존재해야만 한다. 다음과 같은 작업으로, 클래스를 만들고, 테스트 케이스를 구동할 수 있다.

  1. TestCase 내부에 Application 클래스 생성

    클래스 내부에, 임시 구동을 위한 Application을 아래와 같이 생성한다.

     

    @SpringBootApplication

    public static class TestApplication {}

     

  2. 만약 외부에 참고해야 할 Component 들이 존재한다면, 해당 경로를 설정해 준다.

    보통 SprinbBootApplication Annotation을 추가하게 되면, 자동으로 Component들을 Import 한다. 하지만, 대상이 되는 Component들이 해당 클래스의 하위 클래스 들로만 한정되기 때문에, 1번으로 인해 TestCase 내부에 생성된 TestApplication은 외부 참조를 수행하지 못하게 된다. Pakcage나 Classes 레벨로 추가할 수 있다.

     

    @ComponentScan(basePackages = {…})

     

  3. Entity 클래스와 Repository Interface의 필수 Annotation을 확인한다.

    Entity 클래스의 경우는 필수적으로 Entity Annotation이 클래스에 추가되어 있어야 하며, Repository의 경우는, Repository Annotation이나, JpaRepository<T, U>를 상속 받아야 한다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다