@BootstrapWith이 중복으로 사용되어서 발생하는 에러
@SpringBootTest 와 @WebMvcTest 둘다 @BootstrapWith를 가지고 있는 어노테이션이다.
똑같은 어노테이션을 사용하는 어노테이션을 사용해서 발생한 문제
내 코드
package com.example.everytime.controller;
import com.example.everytime.domain.posts.Post;
import com.example.everytime.domain.posts.PostRepository;
import com.example.everytime.dto.PostSaveRequestDto;
import org.junit.After;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.UUID;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
//@WebMvcTest(controllers = PostControllerTest.class) --> 에러가 발생한 부분
public class PostControllerTest {
@LocalServerPort
private int port;
@Autowired
private TestRestTemplate restTemplate;
@Autowired
private PostRepository postRepository;
@After
public void tearDown() throws Exception{
postRepository.deleteAll();
}
@Test
@Transactional
public void Post_등록된다() throws Exception{
//given
String title = "title";
String contents = "content";
PostSaveRequestDto requestDto = PostSaveRequestDto.builder()
.title(title)
.contents(contents)
.build();
String url = "http://localhost:"+ port + "/api/v1/posts";
//when
ResponseEntity<UUID> responseEntity = restTemplate.postForEntity(url,requestDto, UUID.class);
//then
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(responseEntity.getBody()).isNotNull();
List<Post> all = postRepository.findAll();
assertThat(all.get(0).getTitle()).isEqualTo(title);
assertThat(all.get(0).getContents()).isEqualTo(contents);
}
}
두 어노테이션이 어느 경우에 사용되는지, 어떤 용도로 사용되고 있는지 간단하게 알아보면
공식문서에 따르면 @BootStrapWith 가 포함되어있는 것을 확인할 수 있고.
스프링부트를 기반으로 한 테스트를 위한 클래스를 지정하는 어노테이션이다.
다음과 같은 특징을 가지고있다.
이러한 특징때문에 통합 테스트를 할 때 많이 사용하며, 테스트에 필요한 빈만을 등록하여 테스트를 진행하고자 하기 위해서는 @WebMvcTest 를 사용하는 것이 더 효율적임.
MVC를 위한 테스트이며, 웹에서 테스트하기 힘든 컨트롤러를 테스트하는데 적합하다.
이 어노테이션을 사용하면 MVC 테스트와 관련된 어노테이션만 활성화 된다. 이를테면 @Controller, @ControllerAdvice, @JsonComponent, Converter/GenericConverter, Filter 등등.. 그렇기 때문에 @SpringBootTest 어노테이션보다 가볍게 테스트할 수 있다.
전체 애플리케이션 구성을 로드하고, mockMvc를 사용할 경우 SpringBootTest를 사용하는 것을 고려하는게 적절하다.