제목: "스프링부트에서 REST API 테스트코드 작성하기"
작성자: tistory(gonyda)
수정일: 2020년9월14일
링크: https://gonyda.tistory.com/14
작성일: 2022년2월11일
@RequiredArgsConstructor
@RestController
@RequestMapping("api/board")
public class BoardApiController {
private final BoardRepository boardRepository;
@PostMapping
public Long save(@RequestBody BoardDto dto) {
Board board = dto.toEntity();
return boardRepository.save(board).getId();
}
@Transactional
@PutMapping("/{id}")
public Long update(@PathVariable Long id, @RequestBody BoardDto dto) {
Board board = boardRepository.findById(id).orElse(null);
Long updateID = dto.update(board);
return updateID;
}
@Transactional
@DeleteMapping("/{id}")
public Long delete(@PathVariable Long id) {
boardRepository.deleteById(id);
return id;
}
}
@Transactional
컨트롤러에 걸었다.@Transactional
@Rollback
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class BoardApiControllerTest {
@LocalServerPort
private int port;
@Autowired
private TestRestTemplate restTemplate;
@Autowired
private BoardRepository boardRepository;
@AfterEach
public void clean() {
boardRepository.deleteAll();
}
@DisplayName("게시글 저장 테스트")
@Test
void saveBoard(){
//given
String title = "테스트 제목";
String content = "테스트 본문";
String author = "테스트 계정";
BoardDto dto = new BoardDto(title, content, author);
String url = "http://localhost:"+port+"/api/board";
//when
ResponseEntity<Long> response = restTemplate.postForEntity(url, dto, Long.class);
//then
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(response.getBody()).isGreaterThan(0L);
List<Board> list = boardRepository.findAll();
assertThat(list.get(0).getAuthor()).isEqualTo(author);
assertThat(list.get(0).getTitle()).isEqualTo(title);
assertThat(list.get(0).getContent()).isEqualTo(content);
}
@DisplayName("게시글 수정 테스트")
@Test
void modifyBoard(){
//given
Board saved = boardRepository.save(Board.builder()
.title("title")
.content("content")
.author("author")
.build());
Long id = saved.getId();
String updatedTitle = "title1";
String updatedContent = "content1";
BoardDto boardDto = BoardDto.builder()
.title(updatedTitle)
.content(updatedContent)
.build();
String url = "http://localhost:"+port+"/api/board/"+id;
HttpEntity<BoardDto> requestEntity = new HttpEntity<>(boardDto);
//when
ResponseEntity<Long> responseEntity = restTemplate.exchange(url, HttpMethod.PUT, requestEntity, Long.class);
//then
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(responseEntity.getBody()).isGreaterThan(0L);
List<Board> list = boardRepository.findAll();
assertThat(list.get(0).getTitle()).isEqualTo(updatedTitle);
assertThat(list.get(0).getContent()).isEqualTo(updatedContent);
}
@DisplayName("게시글 삭제 테스트")
@Test
void deleteTest(){
//given
Board saved = boardRepository.save(Board.builder()
.title("title")
.content("content")
.author("author")
.build());
//when
String url = "http://localhost:"+port+"/api/board/"+saved.getId();
ResponseEntity<Long> responseEntity = restTemplate.exchange(url, HttpMethod.DELETE, null, Long.class);
//then
assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(responseEntity.getBody()).isGreaterThan(0L);
List<Board> deleted = boardRepository.findAll();
assertThat(deleted).isEmpty();
}
}
spring-boot-test
의존성을 추가하면 @SpringBootTest
라는 어노테이션을 사용할 수 있다
이 어노테이션을 사용하면 테스트에서 사용할 ApplicaitonContext
를 쉽게 생성하고조작할 수 있다.
기존 Spring-test에서 사용하던 @ContextConfiguration
의 발전된 기능이라고 할 수 있다
@SpringBootTest
는 매우 다양한 기능들을 제공한다.
전체 빈 중 특정 빈을 선택하여 생성한다든지, 특정 빈을 Mock으로 대체한다든지, 테스트에 사용할 프로퍼티 파일을 선택하거나 특정 속성만 추가한다던지, 특정 Configuration을 선택하여 설정할 수도 있다.
또한, 주요 기능으로 테스트 웹 환경을 자동으로 설정해주는 기능이 있다.
@SpringBootTest
의 WebEnvironment
속성은 테스트 웹 환경을 설정하는 속성이며, 기본값은SpringBootTest.WebEnvironment.MOCK
이다.
WebEnvironment.MOCK
은 실제 서블릿 컨테이너를 띄우지 않고 서블릿 컨테이너를 mocking 한 것이 실행된다.
MockMvc
를 주입받아 테스트한다.스프링 부트의 내장 서버를 랜덤 포트로 띄우려면 WebEnvironment.RANDOM_PORT
로 설정하면 된다.
WebEnvironment.MOCK
을 사용할 때와는 달리 TestRestTemplate
를 주입받아 테스트한다@SpringBootTest
와 TestRestTemplate
을 사용한다면 편리하게 웹 통합 테스트를 할 수 있다
TestRestTemplate
은 이름에서 알 수 있듯이 RestTemplate
의 테스트를 위한 버전이다
@SpringBootTest
에서 Web Environment
설정을 하였다면 TestRestTemplate
은 그에 맞춰서 자동으로 설정되어 빈이 생성된다