[Routine] 13 주차 시작!
in Daily on Routine
![[Routine] 13 주차 시작!](/assets/img/daily/routine/2023/2023-04-16/2023-04-16-myroutine-13th.png)
“2023년 4월 10일 부터 4월 16일 까지의 나의 루틴.”
#목차
2023-04-10
- 오늘도 어김없이 영한 님과, 동욱 님과 함께 출근하였다.
- 요새 동욱 님의 책을 보는데,
TDD
와Spring Security
,Google
과Naver
의ID
,PW
를 활용한 인증 절차인OAuth
사용 방법을 읽고 있다. - 내가 회사에서 할 땐 엄청 어려웠던 거 같은데, 역시 고수분들이 하는 건 엄청 쉽게 하는 거 같은 느낌이 든다.
- 결국 반복의 중요성 같다.
- 해당 내용을 나의 사이드 프로젝트에 적용시켜야겠다.
2023-04-11
- 오늘도 어김없이 영한 님과, 향로 님과 함께!
HelloControllerTest로 알아보는 Test 어노테이션
//@RunWith(StringRunner.class) // JUnit4 버전 <-> JUnit5 버전 @ExtendWith(SpringExtension.class)
@ExtendWith(SpringExtension.class) // 1) JUnit5 버전 <-> JUnit4 버전 //@RunWith(StringRunner.class)
@WebMvcTest(controllers = HelloController.class) // 2)
public class HelloControllerTest {
@Autowired // 3)
private MockMvc mvc; // 4)
@Test
public void hello가_리턴된다() throws Exception {
String hello = "hello";
mvc.perform(get("/hello")) // 5)
.andExpect(status().isOk()) // 6)
.andExpect(content().string(hello)); // 7)
}
}
@ExtendWith(SpringExtension.class)
:JUnit5
에서@RunWith(StringRunner.class)
이@ExtendWith(SpringExtension.class)
로 바뀌었다.@RunWith(StringRunner.class)
:JUnit4
에서 사용- 테스트를 진행할 때
JUnit
에 내장된 실행자 외에 다른 실행자를 실행 - 여기서는
SpringRunner
라는 스프링 실행자를 사용 - 즉,
스프링 부트 테스트
와JUnit
사이에 연결자 역할
- 테스트를 진행할 때
@WebMvcTest
- 여러 스프랭 테스트 어노테이션 중,
Web(Spring MVC)
에 집중할 수 있는 어노테이션. - 선언할 경우
@Controller
,@ControllerAdvice
등을 사용할 수 있다. - 단,
@Service
,@Component
,@Respository
등은 사용할 수 없다. - 여기서는
Controller
만 사용하기 때문에 선언
- 여러 스프랭 테스트 어노테이션 중,
@Autowired
: 스프링이 관리하는 빈(Bean)을 주입private MockMvc mvc;
- Web API를 테스트 할 때 사용
- 스프링 MVC 테스트의 시작점
- 이 클래스를 통해
HTTP GET, POST
등에 대한API
테스트
mvc.perform(get("/hello"))
MockMvc
를 통해/hello
주소로HTTP GET
요청- 체이닝이 지원되어 아래와 같이 여러 검증 기능을 이어서 선언
.adnExpect(status().isOk())
mvc.perform
의 결과를 검증HTTP Header
의Status
를 검증- 우리가 흔히 알고 있는
200
,404
,500
등의 상태를 검증 - 여기선
OK
즉,200
인지 아닌지를 검증
.adnExpect(content().string(hello))
mvc.perform
의 결과를 검증- 응답 본문의 내용을 검증
Controller
에서"hello"
를 리턴하기 때문에 이 값이 맞는지 검증
Commit with 60~65p test 코드의 어노테이션 설명 및 테스트
2023-04-12
- 오늘도 어김없이 영한 님과, 향로 님과 함께!
- 오늘 향로님의 책을 읽고 테스트하는 도중 gradle 버전에 따른 lombok 이슈를 발견하였다.
// file: "build.gradle"
dependencies {
// Gradle 5.x 미만
// implementation 'org.projectlombok:lombok'
// Gradle 5.x 이상
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
}
- 위 코드 처럼 gradle 버전에 따른 Lombok 설정이 다르다.
- gradle 버전 확인은 터미널에서
./gradlew --version
로 확인 가능하다.
Commit with 66~77p 롬복설정 및 dto 테스트
2023-04-13 스터디 발표
- 오늘도 어김없이! 영한 님, 동욱 님과 함께!
spring boot 프로젝트에 인메모리형 데이터베이스 h2 추가
// file: "build.gradle"
dependencies {
// JPA 설정
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// h2 database
runtimeOnly 'com.h2database:h2'
}
- 위 스프링 버전과
gradle
버전에 따른jpa
설정 방법과h2 database
설정 방법이 다를 수 있다.
자바빈 규약의 Getter/Setter
- 자바빈 규약을 생각하면서
getter/setter
를 무작정 생성하는 경우가 있는데, 이렇게 되면 해당 클래스의 인스턴스 값들이 언제 어디서 변화하는지 코드상으로 명확하게 구분할 수가 없어, 차후 기능 변경 시 정말 복잡해진다. - 그래서
Entity
클래스에서는 절대Setter
메서드를 만들지 않는다. - 대신, 해당 필드의 값 변경이 필요하면 명확히 그 목적과 의도를 나타낼 수 있는 메서드를 추가해야만 한다.
// file: "자바빈 규약의 잘못된 예.java"
public class Order {
public void setStatus(boolean status) {
this.status = status;
}
}
public void 주문서비서의_취소이벤트() {
order.setStatus(false);
}
- 위 코드는
setter
메서드를 이용하여status
의 값을 직접 변경하고 있다. - 이러한 코드는 추후 값들이 변경 될 때마다 다른 쪽에서 사용할때 엉뚱한 값이 나타낼 수 있는 이슈가 발생하게 된다.
- 특히 중요한
결제
와 같은 돈에 관련된 문제가 발생할 수 있기 때문에주의
해야 한다.
// file: "자바빈 규약의 올바른 사용 예.java"
public class Order {
public void cancelOrder() {
this.status = false;
}
}
public void 주문서비서의_취소이벤트() {
order.cancelOrder();
}
- 그렇다면 위 문제
Setter
가 없는 상황에서 어떻게 값을 채워DB
에 삽입(insert
)을 해야 할까? - 기본적인 구조는 생성자를 통해 최종값을 채운 후
DB
에 삽입하는 것이며, 값 변경이 필요한 경우 해당 이벤트에 맞는 public 메서드를 호출 하여 변경하는 것을 전제로 한다. - 또 다른 방법은
@Builder
를 통해 제공되는 빌터 클래스를 사용하게 된다. - 생성자나 빌더나 생성 시점에서 값을 채워주는 역할은 똑같지만, 생성자의 경우 지금 채워야 할 필드가 무엇인지 명확히 지정할 수 가 없다.
// file: "생성자의 경우 지금 채워야할 필드가 무엇인지 명확히 지정할 수 없는 문제.java"
public class ExampleCode {
public Example(String a, String b) {
this.a = a;
this.b = b;
}
}
// file: "@Builer를 사용하여 어떤 값을 채워야 할지 명확하게 인지.java"
public class ExampleCode {
public Example ex() {
return Example.builder()
.a(a)
.b(b)
.build();
}
}
JpaRepository<Entity 클래스, PK 타입>
를 상속하면 기본적인CRUD
메서드가 자동으로 생성@Repository
를 추가할 필요도 없다.- 주의!
Entity
클래스와 기본Entity Repository
는 함께 위치해야 하는 점.- 둘은 아주 밀접한 관계이고,
Entity
클래스는 기본Repository
없이는 제대로 역할을 할 수 가 없다. 나중에 프로젝트 규모가 커져 도메인별로 프로젝트를 분리해야 한다면 이때
Entity
클래스와 기본Repository
는 함께 움직여야 하므로 도메인 패키지에 함께 관리하게 된다.- 예를 들어
new Example(b, a)
처럼a
와b
의 위치를 변경해도 코드를 실행하기 전까지는 문제를 찾을 수 없는 문제가 발생한다. - 하지만
@Builder
를 사용하게 되면 어느 필드에 어떤 값을 채워야 할지 명확하게 인지 할 수 있다.
스터디 발표
- 승연씨 - OSI 7 계층 TCP/IP
- 4계층 : Application Layer
- 3계층 : Transport Layer
LISTEN
: 열려 있음(=/= 통신중) 즉, 응답 대기 상태ESTABLISHED
: 통신중 즉, 상호 연결상태CLOSED
: 연결이 끊어짐SYS-SENT
: 연결을 요청한 상태SYN_RECEIVED
: 연결 요청에 응답후 확인을 기다리고 있음TIME_WAIT
: 연결은 종료되었으나 원격의 수신 보장을 위해 기다리고 있는 상태netstat –an | grep LISTEN
(현재 열려있는 모든 포트)netstat –an | grep ESTABLISHED | wc –l
(모든 서비스 동시 접속자 수)netstat –an | grep :80 | ESTABLISHED | wc –l
(웹 동시 접속자 수)netstat –an | grep –E “포트번호|포트번호|….”
(원하는 포트의 네트워크 상태만 보고 싶을 때 사용)
- 2계층 : 인터넷 계층
- 1계층 : 네트워크 계층(링크)
- NIC 장치를 통해 이더넷의 주소를 뽑아낸 것이 MAC 주소이다.
- 코드 지우개 - 람다식
@FunctionalInterface
->@FunctionalInterface
어노테이션을 사용하면 하나의 추상 메소드만 가지는지 컴파일러가 체크하도록 하여 두 개 이상의 추상 메소드가 선언되어 있으면 컴파일 오류를 발생시킨다.- jquery 이벤트 함수 연속 호출
2023-04-14
- 오늘도 어김없이! 영한 님, 동욱 님과 함께!
@Transactional 이란
@Transactional
이 붙은 메서드는 메서드가 포함하고 있는 작업 중에 하나라도 실패할 경우 전체 작업을 취소한다.- Test 환경에서의 (
TestTransaction.제공메서드
)는 메서드가 종료될 때 자동으로 RollBack 된다.
2023-04-15
JPA Auditing이란
- JPA가 createDate, modifyDate를 자동으로 설정해주게 된다.
2023-04-16
스프링 부트와 AWS로 혼자 구현하는 웹 서비스
- 해당 책에서는
mustache
를 이용하여view
를 구성하지만thymeleaf
를 사용하여view
를 구성 할 예정.
Back to [Routine] 12 주차 시작!
Continue with [Routine] 14 주차 시작!