REST API(3) Event 생성 API 구현 - Event Controller 테스트 만들기
구현 Package 및 Class
EventControllerTests 클래스 생성
우선 테스트 클래스를 생성하면 @RunWith(SpringRunnder.class)
어노테이션을 붙여주어야 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package me.hantomas.restapi.events;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
@RunWith(SpringRunner.class)
@WebMvcTest
public class EventControllerTests {
@Autowired
MockMvc mockMvc;
@Test
public void createEvent(){
}
}
@WebMvcTest
:MockMvc
bean을 자동 설정 해준다. 웹과 관련된 빈만 등록해 주기 때문에 슬라이싱 테스트라고 한다.MockMvc
: 스프링 MVC 테스트의 핵심 클래스이다. Mocking되어 있는 DispatcherServlet을 상대로 가짜 요청을 보내고 그 응답을 확인할 수 있는 테스트를 만들 수 있다. 웹 서버를 띄우지 않고도 스프링 MVC (DispatcherServlet)가 요청을 처리하는 과정을 확인 할 수 있기 때문에 컨트롤러 테스트용으로 자주 쓰인다. 웹 서버를 띄우지 않아서 빠르긴 하지만 DispatcherServlet 까지 만들어야 되기 때문에 단위 테스트보다는 빠르진 않다.
EventControllerTests 구현 (1)
- 입력값들을 전달하면 JSON 응답으로 201이 나오는지 확인 해보자.
Location Header
에 생성된이벤트를 조회할 수 있는 URI
가 담겨 있는지 확인해 보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package me.hantomas.restapi.events;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.hateoas.MediaTypes;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringRunner.class)
@WebMvcTest
public class EventControllerTests {
@Autowired
MockMvc mockMvc;
@Test
public void createEvent() throws Exception{
mockMvc.perform(post("/api/events/")
.contentType(MediaType.APPLICATION_JSON_UTF8)
.accept(MediaTypes.HAL_JSON)
)
.andDo(print())
.andExpect(status().isCreated())
;
}
}
perform()
안에 HTTP 요청을 보낼 수 있는데,contentType()
을 사용해서 요청의 본문에 들어가는 형식과accept()
를 사용해서 원하는 응답 형식을 지정할 수 있다.andExpect()
로 응답을 받아올 수 있다.status().isCreated()
는201
응답을 의미한다.andDo(print())
를 통해서 실제 값들이 어떻게 나오는지 확인할 수 있다.
EventController 구현 (1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package me.hantomas.restapi.events;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import java.net.URI;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
@Controller
public class EventController {
public ResponseEntity createEvent(){
URI createdUri = linkTo(methodOn(EventController.class).createEvent()).slash("{id}").toUri();
return ResponseEntity.created(createdUri).build();
}
}
@Controller
어노테이션을 추가해 준다.@PostMapping("/api/events")
: “/api/events” 경로로의POST
요청을 처리하는 메서드를 정의 한다는 것을 의미한다.- linkTo() 메서드를 통해 link를 만들어 줄 수 있다.
methodOn(EventController.class).createEvent())
는EventController
클래스 안에 메서드createEvent()
에 대한 링크(@RequestMapping("/api/events")
을 통해/api/events"
를 요청하는)를 만든다는 의미이다.linkTo(methodOn(EventController.class).createEvent()).slash("{id}").toUri();
👉http://localhost/api/events/{id}
EventControllerTests 결과값 (1)
EventControllerTests 구현 (2)
- 입력값들을 전달하면 JSON 응답으로 201이 나오는지 확인 해보자.
Location Header
에 생성된이벤트를 조회할 수 있는 URI
가 담겨 있는지 확인해 보자.- 임의의 id값(10)을 넣어주고 결과로 나오는지 확인해 보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package me.hantomas.restapi.events;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.hateoas.MediaTypes;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import java.time.LocalDateTime;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringRunner.class)
@WebMvcTest
public class EventControllerTests {
@Autowired
MockMvc mockMvc;
@Autowired
ObjectMapper objectMapper;
@Test
public void createEvent() throws Exception{
Event event = Event.builder()
.name("Spring")
.description("REST API Development With Spring")
.beginEnrollmentDateTime(LocalDateTime.of(2024,02,19,14,21))
.closeEnrollmentDateTime(LocalDateTime.of(2024,02,20,14,21))
.beginEventDateTime(LocalDateTime.of(2024,02,21,14,21))
.endEventDateTime(LocalDateTime.of(2024,02,22,14,21))
.basePrice(100)
.maxPrice(200)
.limitOfEnrollment(100)
.location("강남역 D2 스타트업 팩토리")
.build();
mockMvc.perform(post("/api/events/")
.contentType(MediaType.APPLICATION_JSON_UTF8)
.accept(MediaTypes.HAL_JSON)
.content(objectMapper.writeValueAsString(event))
)
.andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("id").exists())
;
}
}
ObjectMapper
: 우리는 요청할 데이터의 contentType을 JSON으로 설정했다. 따라서 값을 JSON으로 줘야하는데, SpringBoot에는 이미ObjectMappper
가 빈으로 등록이 되어있어서,.content(objectMapper.writeValueAsString(event))
을 통해 객체를 JSON 문자열로 바꾸어 본문에 넣어 줄 수 있다.
EventController 구현 (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package me.hantomas.restapi.events;
import org.springframework.hateoas.MediaTypes;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import java.net.URI;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
@Controller
@RequestMapping(value = "/api/events", produces = MediaTypes.HAL_JSON_UTF8_VALUE)
public class EventController {
@PostMapping
public ResponseEntity createEvent(@RequestBody Event event){
URI createdUri = linkTo(EventController.class).slash("{id}").toUri();
event.setId(10);
return ResponseEntity.created(createdUri).body(event);
}
}
@RequestMapping(value = "/api/events", produces = MediaTypes.HAL_JSON_UTF8_VALUE)
: RequsetMapping 안에 있는 모든 핸들러들은 HAL_JSON_UTF8_VALUE 타입의 응답을 보내게 된다.@PostMapping
의 경로는 지워줘도 된다.@RequestBody Event event
: 요청 본문에 있는 데이터를event
에 매핑한다.methodOn()
지정을 풀어준다.- 임의의 id(10)을
event.setId(10);
지정해 준다. .body(event);
객체를 body에 담아서 보내준다.
EventControllerTests 결과값 (2)
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.