Spring

스프링 부트 Test(어노테이션)

통촏하여주시옵소서 2024. 11. 16. 20:17

1. @SpringBootTest

개요

  • 설명: 스프링 컨텍스트 전체를 로드하여 통합 테스트(Integration Test)를 수행합니다. 주로 애플리케이션의 전반적인 동작을 검증할 때 사용됩니다.
  • 특징:
    • 모든 빈(bean)을 로드하므로 실행 속도가 느릴 수 있습니다.
    • webEnvironment 속성을 통해 테스트 환경을 설정할 수 있습니다.

코드 예제

@SpringBootTest
class ApplicationTests {

    @Test
    void contextLoads() {
        // 스프링 컨텍스트가 정상적으로 로드되는지 확인
    }
}

webEnvironment 옵션

  • WebEnvironment.NONE: 웹 환경 없이 테스트 실행.
  • WebEnvironment.MOCK: MockServletContext를 사용하여 테스트.
  • WebEnvironment.RANDOM_PORT: 임의의 포트를 사용해 내장 서버 실행.
  • WebEnvironment.DEFINED_PORT: application.properties에 정의된 포트를 사용.
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class WebEnvironmentTests {
    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    void testEndpoint() {
        String response = restTemplate.getForObject("/hello", String.class);
        assertEquals("Hello, World!", response);
    }
}

2. @WebMvcTest

개요

  • 설명: 웹 계층(Web Layer)만 테스트하기 위한 어노테이션입니다. 컨트롤러와 관련된 빈만 로드하며, 서비스나 데이터베이스 관련 빈은 로드하지 않습니다.
  • 특징:
    • 가볍고 빠르게 웹 계층만 검증 가능.
    • @MockBean을 사용해 의존성을 모의(Mock) 처리.

코드 예제

@WebMvcTest(HelloController.class)
class HelloControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void testHelloEndpoint() throws Exception {
        mockMvc.perform(get("/hello"))
                .andExpect(status().isOk())
                .andExpect(content().string("Hello, World!"));
    }
}

@MockBean 예제

@WebMvcTest(UserController.class)
class UserControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private UserService userService;

    @Test
    void testGetUser() throws Exception {
        when(userService.getUserById(1L)).thenReturn(new User("홍길동"));

        mockMvc.perform(get("/users/1"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.name").value("홍길동"));
    }
}

3. @DataJpaTest

개요

  • 설명: JPA와 관련된 데이터 계층(Data Layer)만 테스트하기 위한 어노테이션입니다. @EntityRepository만 로드하며, 데이터베이스와의 상호작용을 테스트합니다.
  • 특징:
    • 기본적으로 테스트용 내장 데이터베이스(H2)를 사용.
    • 빠른 속도로 데이터 계층 검증 가능.

코드 예제

@DataJpaTest
class UserRepositoryTest {

    @Autowired
    private UserRepository userRepository;

    @Test
    void testSaveAndFindUser() {
        User user = new User("홍길동");
        userRepository.save(user);

        Optional<User> foundUser = userRepository.findById(user.getId());
        assertTrue(foundUser.isPresent());
        assertEquals("홍길동", foundUser.get().getName());
    }
}

4. @MockBean@SpyBean

개요

  • @MockBean: 스프링 컨텍스트에서 실제 빈을 대체하는 모의(Mock) 객체를 생성합니다. 주로 서비스 계층이나 외부 API 호출 의존성을 처리할 때 사용합니다.
  • @SpyBean: 기존 빈의 일부 동작만 모의 처리(Spy)할 때 사용합니다.

코드 예제

@MockBean 사용

@SpringBootTest
class OrderServiceTest {

    @MockBean
    private PaymentService paymentService;

    @Autowired
    private OrderService orderService;

    @Test
    void testPlaceOrder() {
        when(paymentService.processPayment(any())).thenReturn(true);

        boolean result = orderService.placeOrder(new Order());
        assertTrue(result);
    }
}

@SpyBean 사용

@SpringBootTest
class OrderServiceTest {

    @SpyBean
    private PaymentService paymentService;

    @Autowired
    private OrderService orderService;

    @Test
    void testPlaceOrder() {
        doReturn(true).when(paymentService).processPayment(any());

        boolean result = orderService.placeOrder(new Order());
        assertTrue(result);
    }
}

5. @RestClientTest

개요

  • 설명: REST 클라이언트를 테스트하기 위한 어노테이션입니다. RestTemplate 또는 WebClient와 같은 HTTP 클라이언트를 모의(Mock) 처리하여 테스트할 때 유용합니다.
  • 특징:
    • 외부 API와의 상호작용을 모의 처리.
    • MockRestServiceServer를 제공하여 응답 시뮬레이션 가능.

코드 예제

@RestClientTest(ApiClient.class)
class ApiClientTest {

    @Autowired
    private ApiClient apiClient;

    @Autowired
    private MockRestServiceServer mockServer;

    @Test
    void testGetDataFromApi() {
        mockServer.expect(requestTo("/api/data"))
                  .andRespond(withSuccess("{\"name\":\"홍길동\"}", MediaType.APPLICATION_JSON));

        ApiResponse response = apiClient.getData();
        assertEquals("홍길동", response.getName());
    }
}

6. @Transactional

개요

  • 설명: 테스트에서 트랜잭션을 관리하며, 테스트가 종료되면 자동으로 롤백(Rollback)됩니다.
  • 특징:
    • 데이터베이스 상태를 변경하지 않고 테스트 가능.
    • @DataJpaTest에 기본 포함되어 있음.

코드 예제

@SpringBootTest
@Transactional
class TransactionalTest {

    @Autowired
    private UserRepository userRepository;

    @Test
    void testSaveUser() {
        userRepository.save(new User("홍길동"));

        assertEquals(1, userRepository.findAll().size());
        // 테스트 종료 후 롤백됨
    }
}

7. @TestConfiguration

개요

  • 설명: 테스트 전용 빈 설정을 제공하는 어노테이션입니다. 테스트 시 특정 빈을 오버라이드하거나, 추가적인 빈을 정의할 때 사용됩니다.

코드 예제

@TestConfiguration
class TestConfig {

    @Bean
    public PaymentService paymentService() {
        return new MockPaymentService();
    }
}

@SpringBootTest
@Import(TestConfig.class)
class PaymentServiceTest {

    @Autowired
    private PaymentService paymentService;

    @Test
    void testPaymentService() {
        assertTrue(paymentService.processPayment(new Payment()));
    }
}