💐 Spring/Spring REST API

3) [test] 입력값 제한하기 (무시하는 방법) - 스프링 REST API

2020. 9. 9. 15:30
목차
  1. 테스트 할 것
  2. 입력값 제한
  3. 통합 테스트로 전환
  4. EventController.class
  5. EventDTO.class
  6. EventControllerTests.class
반응형

테스트 할 것

  • 입력값으로 누가 id나 eventStatus, offline, free 이런 데이터까지 같이 주면?
    • Bad_Request 로 응답 vs 받기로 한 값 이외는 무시! (이번 테스트 방법)

입력값 제한

  • id 또는 입력 받은 데이터로 계산해야 하는 값들은 입력 받지 않아야 한다.
  • EventDTO 적용

DTO -> 도메인 객체로 값 복사

  • ModelMapper

의존성 추가

<dependency> 
<groupId>org.modelmapper</groupId> 
<artifactId>modelmapper</artifactId>
<version>2.3.1</version> 
</dependency> 

빈으로 등록 @Configuration 아래에

@Bean
    public ModelMapper modelMapper(){
        return new ModelMapper();
    }

통합 테스트로 전환

  • @WebMvcTest 빼고 다음 애노테이션 추가
    • @SpringBootTest
    • @AutoConfigureMockMvc
  • Repository @MockBean 코드 제거

EventController.class

@Controller
@RequestMapping(value = "/api/events", produces = MediaTypes.HAL_JSON_VALUE)

public class EventController {

    private final EventRepository eventRepository;
    private final ModelMapper modelMapper;

    //생성자가 하나만있고, 받아올 타입이 빈으로 등록되어있으면 autowired 생략 가능
    public EventController(EventRepository eventRepository, ModelMapper modelMapper) {
        this.eventRepository = eventRepository;
        this.modelMapper = modelMapper;
    }

    @PostMapping
    public ResponseEntity createEvent(@RequestBody EventDto eventDto) {
        /*Event event = Event.builder()
                .name(eventDto.getName())
                ...
                .build(); 를 손쉽게 매핑해주는 ModelMapper를 사용하면 된다.*/

        Event event = modelMapper.map(eventDto, Event.class);

        Event newEvent = this.eventRepository.save(event);
        //link를 생성할땐,
        //HATEOAS가 제공하는 linkTo(), methodOn()을 사용
        URI createUri = linkTo(EventController.class).slash(newEvent.getId()).toUri();
        return ResponseEntity.created(createUri).body(event); //201응답을 Uri에 담아서 리턴시킨다.
    }
}

EventDTO.class

package me.iseunghan.demoinflearnrestapi.events;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@Data @Builder @AllArgsConstructor @NoArgsConstructor
public class EventDto {

    private String description;
    private LocalDateTime beginEnrollmentDateTime;
    private LocalDateTime closeEnrollmentDateTime;
    private LocalDateTime beginEventDateTime;
    private LocalDateTime endEventDateTime;
    private String location; // (optional) 이게 없으면 온라인 모임
    private int basePrice; // (optional)
    private int maxPrice; // (optional)
    private int limitOfEnrollment;
}

EventControllerTests.class

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class EventControllerTests {

    @Autowired
    MockMvc mockMvc;

    @Autowired
    ObjectMapper objectMapper;


    @Test
    public void createEvent() throws Exception {
        Event event = Event.builder()
                .id(100)
                .name("Spring")
                .description("REST API Development with Spring")
                .beginEnrollmentDateTime(LocalDateTime.of(2020, 9, 7, 2, 45))
                .closeEnrollmentDateTime(LocalDateTime.of(2020, 9, 8, 2, 45))
                .beginEventDateTime(LocalDateTime.of(2020, 9, 9, 2, 45))
                .endEventDateTime(LocalDateTime.of(2020, 9, 10, 2, 45))
                .basePrice(100)
                .maxPrice(200)
                .limitOfEnrollment(100)
                .location("Daejoen")
                .free(true)
                .offline(false)
                .eventStatus(EventStatus.PUBLISHED)
                .build();
        //Mock객체로 받았기 때문에 save도 안될것이고, NullpointerException이 발생할것이다.
        //그리하여 Mockito.when(eventRepository.save(event)).thenReturn(event);
        //eventRepository.save가 호출이 되면 -> 그다음 event를 리턴하라.
        //Mockito.when(eventRepository.save(event)).thenReturn(event);

        mockMvc.perform(post("/api/events/")
                .contentType(MediaType.APPLICATION_JSON)//본문 요청에 json을 담아서 보내고 있다고 알려줌.
                .accept(MediaTypes.HAL_JSON)//HAL_JSON으로 받는다.
                .content(objectMapper.writeValueAsString(event)))//요청 본문에 넣어준다. objectMapper로 event를 json으로 변환후
                .andDo(print())//어떤 응답과 요청을 받았는지 확인가능.
                .andExpect(status().isCreated())//201요청이 들어왔는지?
                .andExpect(jsonPath("id").exists()) //json에 id가 있는지?
                .andExpect(header().exists(HttpHeaders.LOCATION))//헤더에 Location이 있는지
                .andExpect(header().string(HttpHeaders.CONTENT_TYPE, MediaTypes.HAL_JSON_VALUE))//content-type에 "application/hal+json"가 나오는지?
                .andExpect(jsonPath("id").value(Matchers.not(100)))
                .andExpect(jsonPath("free").value(Matchers.not(true)))
                .andExpect(jsonPath("eventStatus").value(EventStatus.PUBLISHED.name()))
                ;

    }

}

이번 테스트는 @WebMvcTest 가 아닌, @SpringBootTest 이기 때문에 진짜 스프링을 띄워서 @SpringBootApplication 패키지에
모든 빈들을 등록시켜준다. 그러므로, Mockito가 아닌! Controller에서 직접 repository.save를 시켜주면 된다.

반응형
저작자표시 (새창열림)
  1. 테스트 할 것
  2. 입력값 제한
  3. 통합 테스트로 전환
  4. EventController.class
  5. EventDTO.class
  6. EventControllerTests.class
'💐 Spring/Spring REST API' 카테고리의 다른 글
  • 5) [test] 입력값 제한하기 (비즈니스 로직으로 검사) - 스프링 REST API
  • 4) [test] 입력값 제한하기 (Bad_Request 발생) - 스프링 REST API
  • 2) [test] JSON 응답으로 201이 나오는지 확인 - 스프링 REST API
  • 1) Spring-Boot 프로젝트 만들기 - 스프링 REST API
iseunghan
iseunghan
꾸준하게 열심히..
iseunghan
iseunghan

공지사항

  • 어제보다 나은 오늘이 되기 위해 🔥
  • 분류 전체보기 (262)
    • 💐 Spring (14)
      • 개념 및 이해 (2)
      • Spring 핵심 기술 (24)
      • Spring REST API (8)
      • Spring MVC, DB 접근 기술 (7)
      • Spring Security (23)
      • Spring in Action (1)
    • 🌻 JAVA (84)
      • 자바 ORM 표준 JPA 프로그래밍 (20)
      • 알고리즘, 자료구조 (13)
      • 디자인 패턴 (7)
      • 정리정리정리 (43)
      • JUnit (1)
    • 🔖 Snippets (3)
      • Javascript (3)
    • ⚙️ Devops (22)
      • ⛏ Git (11)
      • 🐳 Docker (6)
      • 🐧 Linux (3)
      • 🌈 Jenkins (1)
      • 📬 Kafka (1)
    • 💬 ETC.. (4)
      • 💻 macOS (2)
    • 🌧️ ORM (2)
      • JPA (2)
    • 🐍 Python (3)
    • 📚 Databases (15)
      • 오라클로 배우는 데이터베이스 개론과 실습(2판) (3)
      • RealMySQL 8.0 (8)
    • 🔥 Computer Science (5)
      • 📡 네트워크 (5)
    • 🏷️ 협업 (1)
    • 📜 코딩테스트 (38)
      • BAEKJOON\수학 1, 수학 2 (8)
      • BAEKJOON\재귀 (5)
      • BAEKJOON\브루트 포스 (3)
      • BAEKJOON\정렬 (1)
      • BAEKJOON\백트래킹 (5)
      • BAEKJOON\BFS, DFS (6)
      • BAEKJOON\이분탐색 (1)
      • BAEKJOON\다이나믹 프로그래밍 (9)
      • BAEKJOON\그리디 알고리즘 (0)
    • ✨ ISEUNGHAN (1)

인기 글

전체
오늘
어제
반응형
hELLO · Designed By 정상우.
iseunghan
3) [test] 입력값 제한하기 (무시하는 방법) - 스프링 REST API
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.