스프링 기반 REST API 개발
6. 보강
포스팅 참조 정보
GitHub
공부한 내용은 GitHub에 공부용 Organizations에 정리 하고 있습니다
해당 포스팅에 대한 내용의 GitHub 주소
실습 내용이나 자세한 소스코드는 GitHub에 있습니다
포스팅 내용은 간략하게 추린 핵심 내용만 포스팅되어 있습니다
https://github.com/freespringlecture/spring-rest-api-study/tree/chap06-01_broken_test_modify
해당 포스팅 참고 인프런 강의
https://www.inflearn.com/course/spring_rest-api/dashboard
실습 환경
- Java Version: Java 11
- SpringBoot Version: 2.1.2.RELEASE
1. 깨진 테스트 살펴보기
EventControllerTests.updateEvent()
깨지는 이유 및 기존 소스코드
기존 Manager가 있고 AccessToken이 들어온 경우에는 링크가 추가로 보이고 아니면 안보이게 했어야 하는데 그렇게 하지 않아서 오류가 발생
generateEvent의 Manager가 null
이라서 NullPointerException
이 발생하는 상태
...
private String getBearerToken() throws Exception {
return "Bearer " + getAccessToken();
}
/**
* 인증 토큰을 발급
* @return
* @throws Exception
*/
private String getAccessToken() throws Exception {
// Given
Account freelife = Account.builder()
.email(appProperties.getUserUsername())
.password(appProperties.getUserPassword())
.roles(Set.of(AccountRole.ADMIN, AccountRole.USER))
.build();
this.accountService.saveAccount(freelife);
...
}
...
@Test
@TestDescription("이벤트를 정상적으로 수정하기")
public void updateEvent() throws Exception {
// Given
Event event = this.generateEvent(200);
...
}
...
private Event generateEvent(int index) {
Event event = Event.builder()
.name("event " + index)
.description("test event")
.beginEnrollmentDateTime(LocalDateTime.of(2018, 11, 23, 14, 21))
.closeEnrollmentDateTime(LocalDateTime.of(2018, 11, 24, 14, 21))
.beginEventDateTime(LocalDateTime.of(2018, 11, 25, 14, 21))
.endEventDateTime(LocalDateTime.of(2018, 11, 26, 14, 21))
.basePrice(100)
.maxPrice(200)
.limitOfEnrollment(100)
.location("강남역 D2 스타텁 팩토리")
.free(false)
.offline(true)
.eventStatus(EventStatus.DRAFT)
.build();
return this.eventRepository.save(event);
}
해결방법
updateEvent()
수행시 Account를 신규로 생성해서 Event 생성 메서드에 account 파라메터를 넘겨
Manager를 셋팅해서 저장하도록 수정
getAcessToken
에 포함되어있던 Account 생성 기능을createAccount()
로 리팩토링getBearerToken
을 오버로딩하여boolean needToCreateAccount
을 파라메터로 받는 메서드와 파라메터를 받지 않으면true
를 기본값으로 대입하도록 수정getAccessToken
메서드는needToCreateAccount
파라메터에 따라createAccount()
를 수행하여 회원정보를 생성하도록 수정updeateEvent
메서드를 createAccount()를 수행하여 생성한 account를generateEvent
에 추가로 파라메터 전달generateEvent
메서드가 account 파라메터를 추가로 받으면 Manager에 파라메터로 받은 account를 셋팅해서 저장
index 파라메터만 받는다면 기존과 동일하게 event 객체를 저장generateEvent
에 포함되어있던 Event Builder 를buildEvent
로 리팩토링
// 오버로딩하여 파라메터를 받지 않으면 getAccessToken에 true를 기본 파라메터로 전달
private String getBearerToken() throws Exception {
return getBearerToken(true);
}
// needToCreateAccount 파라메터를 받아서 getAccessToken에 파라메터를 전달
private String getBearerToken(boolean needToCreateAccount) throws Exception {
return "Bearer " + getAccessToken(needToCreateAccount);
}
/**
* 인증 토큰을 발급
needToCreateAccount 파라메터에 따라 createAccount()를 수행하여 회원정보를 생성하도록 수정
* @return
* @throws Exception
*/
private String getAccessToken(boolean needToCreateAccount) throws Exception {
// Given
if(needToCreateAccount)
createAccount();
...
}
// getAcessToken에 포함되어있던 Account 생성 기능을 createAccount()로 리팩토링
private Account createAccount() {
Account freelife = Account.builder()
.email(appProperties.getUserUsername())
.password(appProperties.getUserPassword())
.roles(Set.of(AccountRole.ADMIN, AccountRole.USER))
.build();
return this.accountService.saveAccount(freelife);
}
// Account를 createAccount()를 수행하여 생성하고 generateEvent에 account 파라메터를 추가로 전달
@Test
@TestDescription("이벤트를 정상적으로 수정하기")
public void updateEvent() throws Exception {
// Given
Account account = this.createAccount();
Event event = this.generateEvent(200, account);
...
}
// account 파라메터를 추가로 받으면 Manager에 파라메터로 받은 account를 셋팅해서 저장
private Event generateEvent(int index, Account account) {
Event event = buildEvent(index);
event.setManager(account);
return this.eventRepository.save(event);
}
// index만 있으면 기존과 동일하게 event 객체를 저장
private Event generateEvent(int index) {
Event event = buildEvent(index);
return this.eventRepository.save(event);
}
// generateEvent에 포함되어있던 Event Builder 를 buildEvent로 리팩토링
private Event buildEvent(int index) {
return Event.builder()
.name("event " + index)
.description("test event")
.beginEnrollmentDateTime(LocalDateTime.of(2018, 11, 23, 14, 21))
.closeEnrollmentDateTime(LocalDateTime.of(2018, 11, 24, 14, 21))
.beginEventDateTime(LocalDateTime.of(2018, 11, 25, 14, 21))
.endEventDateTime(LocalDateTime.of(2018, 11, 26, 14, 21))
.basePrice(100)
.maxPrice(200)
.limitOfEnrollment(100)
.location("강남역 D2 스타텁 팩토리")
.free(false)
.offline(true)
.eventStatus(EventStatus.DRAFT)
.build();
}
EventControllerTests.getEvent()
깨지는이유 및 소스코드
마찬가지로 getEvent()
테스트 코드도 generateEvent의 Manager가 null
이라서 NullPointerException
이 발생하는 상태
@Test
@TestDescription("기존의 이벤트를 하나 조회하기")
public void getEvent() throws Exception {
// Given
Event event = this.generateEvent(100);
...
}
해결방법 및 소스코드
createAccount()를 수행하여 생성한 account를 generateEvent
에 추가로 파라메터 전달
// Account를 createAccount()를 수행하여 생성하고 generateEvent에 account 파라메터를 추가로 전달
@Test
@TestDescription("기존의 이벤트를 하나 조회하기")
public void getEvent() throws Exception {
// Given
Account account = this.createAccount();
Event event = this.generateEvent(100, account);
...
}
DemoApplicationTests
깨지는이유 및 소스코드
이 테스트 코드는 application-test.properties
파일에서 설정을 읽어오지 않고 application.properties
파일에서 설정을 읽어오기 떄문에 h2
DB를 사용하지 않고 현재 띄워놓지 않은 PostgreSQL
커넥션을 시도하면서 테스트가 실패함
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {
@Test
public void contextLoads() {
}
}
해결방법 및 소스코드
@ActiveProfiles("test")
어노테이션을 추가해서 application-test.properties
파일에서 설정을 읽어 오도록 수정하면 테스트가 성공한다
@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("test")
public class ApplicationTests {
@Test
public void contextLoads() {
}
}
BaseControllerTest -> BaseTest 로 클래스명 정정
public class BaseTest {
'개발강의정리 > Spring' 카테고리의 다른 글
[스프링 기반 REST API 개발] 6-2. 스프링 부트 2.2.5 버전으로 업데이트 (0) | 2020.04.13 |
---|---|
[스프링 기반 REST API 개발] 5-11. Events API 개선: 출력값 제한하기 (0) | 2020.04.11 |
[스프링 기반 REST API 개발] 5-10. 스프링 시큐리티 현재 사용자 조회 (0) | 2020.04.10 |
[스프링 기반 REST API 개발] 5-9. 이벤트 API 점검 (0) | 2020.04.09 |
[스프링 기반 REST API 개발] 5-8. 문자열을 외부 설정으로 빼내기 (0) | 2020.04.08 |
댓글