[BoostCourse] 프로젝트 5. 예약관리 시스템: 예약하기 (BE)

 

 - 이전 글

 - [부스트코스] 프로젝트 5. 예약관리 시스템: 예약하기 분석 및 설계

 

 

 - 다음 글

 - [부스트코스] 프로젝트5. 예약관리 시스템: 예약하기(FE) 제출 [PASS & Feedback]

 

BE_PJT E-1. 예약관리 시스템: 예약하기

 

 

피드백 요약

 

하단에 작성된 내용은 기능관련 피드백만

1. Service

  • auto seq (key) 기능 사용하기 (ref - link)
SimpleJdbcInsert(docs)

 위 사이트에서 SimpleJdbcInsert라는 내용을 살펴보면

1. SimpleJdbcInsert 클래스 선언

2. setDataSource() 메서드에서 new SimpleJdbcInsert() 클래스 생성

3. withTableName("테이블명").usingGenerateKeyColumns("pk명") chaining 메서드를 통해 필요한 값을 주입

4. AutoGenerated Key 사용할 메서드에서 executeAndReturnKey("파라미터") 메서드를 통해 입력된 값에 대한 Auto-generated Key를 얻을 수 있다.

5. 위 사이트의 예시에서 first_name, last_name을 파라미터로 넣는 이유를 몰랐는데 직접 해보면 테이블에 기본값이 없는 필드는 입력을 해주어야 원하는 key 값을 얻을 수 있다.

 

 위 테이블 보면 product_id, display_info_id, reservation_name, reservation_tel, reservation_email, reservation_date 필드에 "기본값이 없음"을 알 수 있다.

 

ReservationDao.java

 

ReservationDaoTest
ReservationServiceTest.java

위 로그에 132 라는 값을 DB에서 확인

자동증가 132의 값이 리턴되는 것을 알 수 있다.

 


 

현재 프로젝트에 적용되어 있는 클래스는 NamedParameterJdbcTemplate이기 때문에 밑의 내용으로 Generated Key를 구현

 

NamedParameterJdbcTemplate.update 알아보기(docs)

 - update 메서드 중 generatedKeyHolder를 파라미터로 사용하는 메서드가 2개 있다.

 

Issue an update via a prepared statement, binding the given arguments, "returning generated keys".

 

public int update(String sql, SqlParameterSource paramSource, KeyHolder generatedKeyHolder)

NamedParameterJdbcTemplate.update(sql, paramSource, generatedKeyHolder)

 

public int update(String sql, SqlParameterSource paramSource, KeyHolder generatedKeyHolder, String[] keyColumnNames)

NamedParameterJdbcTemplate.update(sql, paramSource, generatedKeyHolder, keyColumnNames)

 

위 update메서드를 통해 리턴받은 generated key

GENERATED_KEY


2. Controller

  • 파라미터의 null이나 공백("") 체크에 대한 조건식 처리
apache에서 제공하는 라이브러리 사용

 

Maven Library

 

참고 사이트

https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/StringUtils.html

 

 

이후 수정한 내용

 - 기존 세션에 대한 로직을 페이지 요청 컨트롤러에서 모두 처리하여 불필요한 코드를 줄여보았다.

[BoostCourse] 테스트 코드 만들기

 * 더 정리가 필요

이 글은 테스트 코드 없이 손으로 그림그려가면서 코딩하는 부족한 날 위한 글

 

 - 사전내용

바쁘다는 핑계로 프로젝트를 뒤로 미루다가 다시 하려니 생각이 잘 안나고.. 리펙토링 해야 할 부분도 많고, 답도 안나오고...
몇 개월전에 『테스트 주도 개발(Test-Driven Development: By Example)』이란 책을 읽고,
내게 부족한 부분을 채워줄 수 있을 것 같아서 흉내내 보았다.

 

 이 글을 쓰는 시점은 PJT 4까지 완료하고 5개월이 지나고 PJT 5를 다시 시작하려한다.
 - 목표
1. src/test/java 폴더에 class 파일 만들기
2. 테스트 클래스에 Annotation 적용하기
3. @Test Annotation을 적용한 테스트 메서드 만들기
4. Controller에 @Mockito 적용하여 API 테스트 작성

 

 - 기존 테스트 코드

기존에도 소스 내에 print()만 안찍었지 비슷한 수준의 테스트 클래스를 작성하여 흉내만 냈었다.

 

 

 - 카테고리 (/api/categories) 결과 값

 

 

위와 같은 자바 클래스를 Repository, Service까지는 대충 적용 되는 것처럼 보인다.
물론 테스트 코드에 대한 개념과 깊이가 없어 데이터를 출력해보는 것 이상의 정보는 보이지 않는다.

 


 

여기서부터가 문제인데 웹 프로젝트에서 request 값이 정상적으로 요청이 들어와
Service Layer, Repository Layer의 함수를 호출하는 것은

단순하게 함수를 호출하여 결과 값이 내가 만든 결과 값이 나오는지 확인이 가능하다.

Controller도 기존에 만들었던 똑같은 테스트 방식으로 파라미터 넣고 호출하도록 했었다.

 

하지만 Controller의 목적은 Model과 View간에 상호 동작을 관리 하는 것이다.

즉, View에서 request한 값을 받아 Model에 전해주고, Model의 결과 값을 View에 전달해주는 것

 

지금처럼 테스트 하면 View에서 request한 값을 받을 수 있는 방법이 없다.

 

그래서 적용한 것이 Mockito이다.

 

 - dependency 추가

spring-test, junit은 기존에 쓰고 있었고, mockito-all만 새로추가

 

 - Controller 테스트 코드

 

 - Mockito 적용 전 참고해야할 설정

web.xml에 설정되어 있는 servlet 설정

AnnotationConfigWebApplicationContext - DispatcherServlet에게 annotation 기반의 자바 설정 로드
WebMvcContextConfiguration - 자바 베이스 스프링 설정

 

 

 - 상단 어노테이션 설정

@RunWith docs

 - 스프링 테스트를 Junit으로 돌리기 위한 어노테이션 

 

@ContextConfiguration docs

 - ApplicationConfig.class, WebMvcContextConfiguration.class를 spring context의 빈 설정 파일로 사용

 * contextConfigLocation로 사용하고 있는 클래스인 WebMvcContextConfiguration 클래스를 @ContextConfiguration에 추가 안하면 Dispatcher가 URL를 매핑할 controller를 찾지못한다.

 

@WebAppConfiguration docs

 - 테스트할 DI 컨테이너를 웹 어플리케이션 전용 DI 컨테이너로 처리

 

위에 내용이 설정되어야 Test 클래스에서 스프링 MVC 동작을 재현할 수 있다.

 

 - MockMvc 선언

  • MockitoAnnotations.iniMocks()
    • @Mock, @Spy, @Captor, @InjectMocks이설정된 객체를 초기화 해준다.
  • MockMvc
    • MockMvc로 초기화된 DispatcherServlet 인스턴스를 반환한다.
  • MockMvcBuilders.webAppContextSetup(WebApplicationContext context)
    • DisplatcherServlet은 스프링 MVC기반 구조와 응용프로그램 컨트롤러를 찾아 ServletContext로 설정된 Context를 사용하도록 한다.
  • MockMvcBuilders.standaloneSetup(Object... controllers)
    • 하나 이상의 @Controller 인스턴스를 등록하거나 스프링 MVC 인프라를 프로그래밍적인 설정을 통해 MockMvc를 빌드한다.

 

 

 - Mock 객체 선언

  • @Mock
    • 테스트에 필요한 객체를 신속하게 생성할 수 있다.
    • 반복적인 모의 생성 코드를 최소하 하도록 한다.
    • 테스트 클래스를 읽기 쉽게 만든다.
    • 필드 이름이 Mock을 식별하는데 사용되어 확인된 오류를 읽기 쉽게 만들어준다.
  • @InjectMock
    • class의 인스턴스를 생성하고 @Mock(또는 @Spy) Annotation으로 생성된 mock instance를 class의 instance에 주입한다.
    • 이 mock instance를 초기화하고 주입하려 @RunWit(MockitoJunitRunner.class) 또는 MockitoAnnotations.init(this)를 사용해야 한다. 

 

 - 테스트에 필요한 static factory 메서드

static factory 메서드 설명
MockMvcRequestBuilders  요청 데이터를 설정할 때 사용할 static 메서드
MockMvcResultMatchers 
실행 결과를 검증할 때 사용할 static 메서드
MockMvcResultHandlers 
실행 결과를 로그 등으로 출력할 때 사용할 static 메서드

 

 - Mockito로 카테고리 API(get: /api/categories) 테스트 코드

 

 

 - Mockito로 카테고리 API(get: /api/categories) 테스트 결과 값

 

 

 - Mockito로 예약 API(get: /api/reservations) 테스트코드

 

 

 - Mockito로 예약 API(get: /api/reservations) 테스트 결과 값

 

 

 - 데이터 결과 값을 Json Viewer를 통해 데이터 확인

 

참고 사이트

 - MockMvc

 - MockitoAnnotations.init()

 - MockitoAnnotations.initMocks() vs @RunWith(MockitoJunitRunner.class)

 - JsonViewer

 

[BoostCourse] 프로젝트 5. 예약관리 시스템: 예약하기

 

 * 이 글은 웹 프로그래밍 과정을 진행하면서 "개인적인" 생각을 정리한 글입니다.
 * 잘못된 부분, 이해가 안 되는 부분 또는 더 좋은 생각이 있으신 분들은 댓글 남겨주세요.

 

 - 다음 글

[부스트코스] 프로젝트5. 예약관리 시스템: 예약하기(BE) 제출 [PASS & Feedback]

 

[참고 문서]

[기획서]  - 부코_웹_PJT3-5_예약서비스.pptx
[Trello]   - boostCourse (작성 중)
 

부코_웹_PJT3-5_예약서비스.pptx

예약서비스

docs.google.com

 

Full Stack Course

Trello is the visual collaboration platform that gives teams perspective on projects. Use Trello to collaborate, communicate and coordinate on all of your projects.

trello.com

 

[목차]

1. 프로젝트 기능 요구사항 정의서
2. 프로젝트 기술 요구사항 정의서
3. 예약하기, 예약확인 시퀀스 다이어그램
4. API Data Flow
5. 예약하기 View 구현 상세
6. 세션 등록 이벤트 시점
7. 예약확인 페이지 JsonData 확인

 

1. 프로젝트 기능 요구사항 정의서

 

2. 프로젝트 기술 요구사항 정의서

 

3. 예약하기, 예약확인 시퀀스 다이어그램

4. API Data Flow

5. 예약하기 View 구현 상세

 

6. 세션 등록 이벤트 시점

7. 예약 확인 페이지 JsonData 확인

 

8. 예약확인 페이지 구현

 

[부스트코스] 웹 프로그래밍 프로젝트 시 느낀 필요한 개념


[JS]

 - JS 버전별 차이

 - JS 변수 타입

 - JS 매커니즘

 - polyfill

 - 함수형 자바스크립트

 - Bubbling & Capturing

 - Templating

 - 비동기 통신으로 요청한 데이터를 재사용할 방법

 - 그 외 등등..

 - JS Debug (https://developers.google.com/web/tools/chrome-devtools/javascript/?hl=ko)

 - 배열의 함수형 메소드 (map, filter, reduce)

 - 객체형 자바스크립트

 - jQuery

 - handlebar

 - Clean Code

 - Carousel Slide ** (이해는 되는데.. 구현이 어설픔)


 * 이제 부터 알아가야 함...


[Spring Framework]

 - Spring Config (XML, Java)

 - Spring Layered Architecture

 - AOP

 - Design Pattern (Singleton)

 - Front Controller (DispatcherServlet)

 - XML Config -> Java Config (https://www.luckyryan.com/2013/02/07/migrate-spring-mvc-servlet-xml-to-java-config/)

 - 설정의 분리

 - MessageConvertor



[BoostCourse] 프로젝트 4. 예약관리 시스템: 상세페이지 (FE)


 - 이전 글


PJT4. 예약관리 시스템: 상세페이지


[프로젝트 4-2 (FE)에 대한 피드백 정리]

 - 필요한 요구사항은 모두 충족하였다.

 - 디버깅 시 작성했던 코드는 테스트 후 삭제하는 습관을 갖는다.

 - 코딩컨벤션을 되새겨보아야 한다. "setXX()이라는 메서드 명이 하는 일"



[코딩 컨벤션] 

 - setXXX() 함수의 역할이 무엇인지 생각해 보아야 한다.



[불필요한 코딩]

 - 테스트를 위한 코딩은 삭제해야 한다.

 - 실제 개발 시에도 배포할 때는 테스트 코드는 삭제



[일관성 있는 코딩 및 불필요한 코딩]

 - 위쪽에서와 달리 여기서 변수 선언 및 초기화를 했다.

 - 굳이 할 필요 없는 코드 였기 때문에 삭제 해야 했다.





[BoostCourse] 프로젝트 4. 예약관리 시스템: 상세페이지 (FE)


 - 이전 글


 - 다음 글 



PJT4. 예약관리 시스템: 상세페이지


[프로젝트 4-2 (FE)에 대한 피드백 정리]

 - 무한슬라이드로 구현을 안해서 Fail !!




[개발 스펙관련..]

 - ES 버전차이에 대한 공부가 안되어있어서 최대한 낮은 버전의 함수와 방식으로 프로젝트를 작성하고 있다.

 - ES6는 찬찬히 하기로 한다...

 - var, const, let의 차이


[JS 경로 이동 함수관련..]

 - a 태그로 어떠한 기능이 구현이 되어 있을 때 href로 이동하기보다 javascript로 기능을 구현하고 싶어서 이런식으로 작성 해봤다.

 - 이런 방법과는 달리 controller에 경로와 파라미터를 보내기 위한 방법이 다른 내용이 있을지도 모른다. (replace("경로")) 라거나..

 - JavaScript로 구현하는 경로 이동


[불필요한 주석관련..]

 - 프로젝트 시작하기 전에 코드가 수정이 되어야 하는 곳에 주석을 작성해놨었다.

 - 구현 후에는 TODO를 지우고 내가 수정했다고 다른 방식으로 표시하도록 하자


[개발 스펙 관련..]

 - 순수 자바스크립트로 프로젝트를 진행하고나서 리펙토링으로 제이쿼리를 사용해보도록한다.







[BoostCourse] 프로젝트 4. 예약관리 시스템: 상세페이지 (BE)


 - 이전 글


 - 다음 글


PJT4. 예약관리 시스템: 상세페이지 (BE)


 - 프로젝트4 제출에 대한 피드백 정리



[Service]

 - Transaction의 개념과 @Transactional의 작동방식, 사용방법 등이 필요한 피드백



[BoostCourse] 프로젝트 4. 예약관리 시스템: 상세페이지 (BE)


 - 이전 글


 - 다음 글


PJT4. 예약관리 시스템: 상세페이지 (BE)



 - 프로젝트4 제출에 대한 피드백 정리



1. 피드백 요약

[피드백]

 1. 하나의 메소드에 하나의 기능 (private 메소드로 구현)

 2. 필요하지 않은 주석 및 코드는 제거



[수정]

 1. controller

  1) MainPageController

   ① 필요없는 코드 삭제 (detail)


 2. dao

  1) displayInfoDao

   ② queryForObject의 예외처리 필요

   ③ displayInfoId값에 대한 예외상황 테스트 소스 필요


  2) productDao

   ① 변경 내용이 없는 Mapper는 final한 변수 처리

   ② java변수 선언 시 필요한 부분에 선언

   ③ 고정적인 값은 상수로 선언


 3. sql

  1) 쿼리에 대한 설명을 작성하되 내용 중간에 넣지 않기


 4. service 

  1) 하나의 메서드에는 하나의 로직(기능)만을 넣기

  2) 로직 구현 시 반복 내용 줄일 수 있는 로직 구현하기


[기능 분리]

 - 하나의 메소드에 하나의 기능만을 사용할 수 있도록 로직 분리


[불필요한 코드 및 주석 제거]

 - 의미 없이 다는 주석을 삭제

[불필요한 메서드 삭제]

 - 우선 페이지 이동을 위한 메소드를 만들어 놨었으나 상세페이지 구현 시 파라미터가 필요하여 다시 만듦

 - 파라미터 없는 메서드 삭제 했어야 함



[항상 예외처리가 필요한 API 로직]

 - 파라미터는 null값과 다른 의도하지 않은 예외 값에 대한 예외처리가 필요

 - 또한 파라미터가 그래도 잘못 들어갔을 경우 queryForObject() 호출 시, EmptyResultDataAccessException 예외처리가 필요


[변경될 일이 없는 내용]

 - static final 



[변수의 선언]

 - 이 내용은 정확하게는 이해를 못함..

 - 변수 선언된 자리가 사용되는 부분과 많이 떨어진 상태가 아니라서 바로 위에 선언해야 하는건가?


[상수 선언시 static final]

 - 프로젝트 구현 시, 상품 데이터를 호출 할 때 고정된 값을 사용하기 때문에 상수 선언을 해줘야 함


[상수로 선언되면 더 좋을 코드]

 - "0"은 전체 리스트라는 값을 표현하기 위해서 사용하고 있었기 때문에 상수로 선언해둘 경우 더 좋을 듯



[주석의 위치]

 - 코드 중간에 주석은 코드를 읽는데 불편함을 줄 수 있다.


[하나의 메소드에는 하나의 기능만]

 - comment 안에 CommnetImage를 가져와야 하는데 그 로직은 따로 메소드로 만들 것


[효율적인 로직]

 - 피드백 해주신 내용대로 불필요한 반복 작업을 줄일 수 있다.


+ Recent posts