| Spring REST API 비즈니스 로직 적용 및 JUnitParam을 이용한 테스트
- JUnitParam 테스트 라이브러리는 JUnit의 각 Test 메서드에 파라미터를 쓸 수 있게 함으로써 테스트 코드량을 줄이고 유지보수를 쉽게 해주는 유용한 라이브러리 이다.
테스트 할 전제조건
- 1. basePrice와 maxPrice 가 모두 0이면 free=true 그 이외에는 free=false
- 2. location 이 null 이거나 문자열의 길이가 0일 때 offline = false 그 외에는 offline = true
참고 URL : https://github.com/Pragmatists/JUnitParams
의존성 추가
<dependency>
<groupId>pl.pragmatists</groupId>
<artifactId>JUnitParams</artifactId>
<version>1.1.1</version>
<scope>test</scope>
</dependency>
테스트코드
package org.kyhslam.rest;
import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
import org.assertj.core.api.Assertions;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(JUnitParamsRunner.class)
public class EventTest {
@Test
@Parameters(method = "paramsForTestFree")
public void testFree(int basePrice, int maxPrice, boolean isFree){
Event event = Event.builder()
.basePrice(basePrice)
.maxPrice(maxPrice)
.build();
// When
event.update();
// Then
Assertions.assertThat(event.isFree()).isEqualTo(isFree);
}
private Object[] paramsForTestFree(){
return new Object[] {
new Object[] {0,0,true},
new Object[] {0,0,true},
new Object[] {0,0,true}
};
}
@Test
@Parameters(method = "paramsForTestOffline")
public void testOffline(String location, boolean isOffline){
// Given
Event event = Event.builder()
.location(location.trim())
.build();
// When
event.update();
// Then
Assertions.assertThat(event.isOffline()).isEqualTo(isOffline);
}
private Object[] paramsForTestOffline(){
return new Object[] {
new Object[] {"강남",true},
new Object[] {null,false},
new Object[] {" ",false}
};
}
}
- JUnitParams를 적용하여 테스트 코드를 작성한 것을 볼 수 있습니다. @Parameters 어노테이션을 각 테스트에 명시하면 파리미터화 된 입력값을 쓸 수 있습니다.
- 파라미터화된 입력값은 위 코드와 같이 코드 상에 명시해야 하며 parametersFor + [테스트명] 으로 작성하면 자동적으로 [테스트명]으로 작성된 테스트 메서드에 해당 입력값이 매칭되게 됩니다. 또한 @Parameters(method="[테스트명]") 형태로 직정 지정해서 쓸 수 있습니다.
소스
package org.kyhslam.rest;
import lombok.*;
import javax.persistence.*;
import java.time.LocalDateTime;
@Builder @AllArgsConstructor @NoArgsConstructor
@Setter @Getter @EqualsAndHashCode(of = "id")
@Entity
public class Event {
@Id @GeneratedValue
private Integer id;
private String name;
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;
private boolean offline;
private boolean free;
@Enumerated(EnumType.STRING)
private EventStatus eventStatus = EventStatus.DRAFT;
public void update(){
if(this.basePrice == 0 && this.maxPrice == 0){
this.free = true;
}else{
this.free = false;
}
// OffLine
if(this.location == null || "".equals(this.location)){
this.offline = false;
}else{
this.offline = true;
}
}
}
비즈니스 로직을 적용한 엔티티 클래스입니다.
package org.kyhslam.rest;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.hateoas.MediaTypes;
import org.springframework.hateoas.mvc.ControllerLinkBuilder;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.validation.Valid;
import java.net.URI;
@Controller
@RequestMapping(value = "/api/events", produces = MediaTypes.HAL_JSON_UTF8_VALUE)
public class EventController {
@Autowired
EventRepository eventRepository;
@Autowired
ModelMapper modelMapper;
@Autowired
EventValidator eventValidator;
public EventController(EventRepository eventRepository, ModelMapper modelMapper, EventValidator eventValidator){
this.eventRepository = eventRepository;
this.modelMapper = modelMapper;
this.eventValidator = eventValidator;
}
@PostMapping
public ResponseEntity createEvent(@RequestBody @Valid EventDto eventDto, Errors errors){
if(errors.hasErrors()){
return ResponseEntity.badRequest().body(errors);
}
eventValidator.validate(eventDto, errors);
if(errors.hasErrors()){
return ResponseEntity.badRequest().body(errors);
}
Event event = modelMapper.map(eventDto, Event.class); // Dto를 event로 변환
event.update();
Event newEvent = eventRepository.save(event);
URI createdUri = ControllerLinkBuilder.linkTo(EventController.class).slash(newEvent.getId()).toUri();
return ResponseEntity.created(createdUri).body(event);
}
}
HTTP 요청 안에 포함된 데이터들을 Event 객체로 역직렬화한 다음 Event 객체의 update 메서드를 이용해 비즈니스 로직을 적용한 모습입니다.
결과
각 Parameter에 따른 테스크 케이스 결과를 볼 수 있다.
'📚 Spring > Spring REST' 카테고리의 다른 글
[Spring REST API #10] Spring REST Docs 개념 및 적용 (0) | 2020.08.05 |
---|---|
[Spring REST API #9] Spring HATEOAS 개념 및 적용 (0) | 2020.08.04 |
[Spring REST API #7] Bad Request 에 대한 본문 메세지 (0) | 2020.07.31 |
[Spring REST API #6] Bad Request (도메인 Validator를 통한 처리) (0) | 2020.07.31 |
[Spring REST API #5] Bad Request 처리 (0) | 2020.07.30 |