IssuedAt : 25 - 09 - 18 (목)
Daily Study : 3
알고리즘
- 프로그래머스 입문 - 나이 출력 하는 것을 풀면서 선생의 나이가 궁금해진 학생이 있다고 해서 나이를 구해야 하는데
바로 Date클래스의 Year를 가지고 오는 메서드가 있지 않을까 ? 생각해보고 메서드를 사용하려는 순간

해당 메서드는 삭제 되었다고 한다
이유가 국제화와 잘 맞지 않는다고 한다. 그래서 생성자와 다른 생성자/메서드도 더 이상 사용되지 않는다고 한다.
해결은 LocalDateTime클래스를 사용하여 해결을 했다.
현재 년도를 가져오려고 하면 아래 코드 처럼 가져오면 된다 !
import java.time.LocalDateTime;
LocalDateTime localDateTime = LocalDateTime.now();
int year = localDateTime.getYear();
JAVA - 클래스, 객체, 인스턴스 정리 & 배열 도입(복습 #2)
- 모든 인스턴스는 객체이지만, 인스턴스라고 부르는 순간은 특정 클래스로부터 그 객체가 생성되었음을 강조하고 싶을 때이다.
예를 들어서 Student1 은 객체이지만, 이 객체가 Student 클래스로부터 생성된다는 점을 명확히 하기 위해 student1 을 Student 의 인스턴스라고 부른다.
- 배열을 사용하면 특정 타입을 연속한 데이터 구조로 묶어서 편리하게 관리할 수 있다.
자바에서 대입은 항상 변수에 들어 있는 값을 복사한다
카카오 사용자 정보로 회원가입 구현
- 카카오 사용자 정보를 가져와서 회원가입을 진행하려고 할 때, 방법이 두 가지가 있다고 한다.
첫 번째는 카카오 방법을 이용한 이용자들을 위한 유저 테이블을 하나 더 만드는 것이고,
두 번째는 기존 테이블에 카카오 유저를 추가하는 것이다.
🔎 두 가지 장단점이 어떤 점이 있을까 ?
카카오 유저를 위한 테이블을 새로 만들게 되면 결합도가 낮아진다. 대신 구현 난이도가 올라가게 된다.
기존회원에 카카오 유저를 추가하게 되면 구현은 단순해지지만, 결합도가 낮아진다.
정처기를 준비하면서 배웠던 개념 중 하나가 결합도는 약하게 하는 것이 좋다는 것이 생각났다
"결합도는 낮추고 응집도를 높이기" 실제로 이 패턴을 적용하기 위해 많은 디자인 패턴이 존재한다.
단위 테스트란 무엇일까?
📒 버그 발견 시간이 늦어짐에 따라 비용이 기하급수적으로 커진다!!
무조건 해야하는 건 아니라고 하지만 나중에 버그가 발견되서 큰 문제가 된다고 하면 반드시 작성하는 게 좋아보인다..
@BeforeEach : 각각의 테스트 코드가 실행되기 전에 수행.
@AfterEach : 각각의 테스트 코드가 실행된 후에 수행.
@BeforeAll : 모든 테스트 코드가 실행되기 전에 최초로 수행.
@AfterAll : 모든 테스트 코드가 실행된 후에 수행.
public class BeforeAfterTest {
@BeforeEach
void setUp() {
System.out.println("각각의 테스트 코드가 실행되기 전에 수행");
}
@AfterEach
void tearDown() {
System.out.println("각각의 테스트 코드가 실행된 후에 수행\n");
}
@BeforeAll
static void beforeAll() {
System.out.println("모든 테스트 코드가 실행되기 전에 최초로 수행\n");
}
@AfterAll
static void afterAll() {
System.out.println("모든 테스트 코드가 수행된 후 마지막으로 수행");
}
@Test
void test1() {
System.out.println("테스트 코드 작성 1");
}
@Test
void test2() {
System.out.println("테스트 코드 작성 2");
}
}
/*
모든 테스트 코드가 실행되기 전에 최초로 수행
각각의 테스트 코드가 실행되기 전에 수행
테스트 코드 작성 1
각각의 테스트 코드가 실행된 후에 수행
각각의 테스트 코드가 실행되기 전에 수행
테스트 코드 작성 2
각각의 테스트 코드가 실행된 후에 수행
모든 테스트 코드가 수행된 후 마지막으로 수행
*/
- 테스트 코드를 작성 중에 @Order 쓰는 것을 확인 했는데 테스트 코드에서도 사용하는 것을 알게 되었다..
우선 @Order 를 사용하게 되면 테스트를 순서대로 실행 되어야 할 때 사용한다는데 테스트 코드가 실행 될 때 순서대로 실행 되지 않아서 명확하게 순서가 중요할 때는 @Order를 사용한다고 알고 가면 좋을 거 같다.
테스트 코드에서 @Order를 사용하기 위해서 선언 해줘야 하는 것이 있는데, 해당 애너테이션을 사용하는 클래스위에다가
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)를 선언 해주어야 한다.
@RepeatedTest : 테스트에서 for문 같은 친구라고 볼 수 있다.
@ParameterizedTest : 파라미터 값을 활용하여 테스트 하는 방법이다.
| @ValueSource({}) : 위 애너테이션과 같이 사용하며 전달 해주고 싶은 파라미터 값을 넣어줄 수 있다. 그리고 여기에 전달되는 파라미터 수 만큼 테스트가 실행 됩니다. 예를 들어서 9개의 파라미터를 전달 해준다고 하면 9번의 테스트 코드가 실행 됨.
- Assertion 테스트 중
계산기 기능을 하는 클래스를 메인 클래스에 만들어 두었고, 테스트 코드에서 사용을 하려고 하는데 Calculator calculator = new Calculator(); 를 바로 하지 않고 변수 선언만 해둔 다음에 @BeforeEach 에서 계산기 변수를 초기화 해주었다 왜 이렇게 사용을 하는 것 일까 ??
아.. 배운 것을 활용하려고 일부러 하셨다고 한다 ㅎㅎ..
📒 given - when - then
테스트 코드 작성도 패턴이 있는데 대중적인 given - then - when 패턴이다.
( given ) 테스트 하고자하는 대상을 실제로 실행하기 전에 테스트에 필요한 값(상태)을 미리 선언합니다.
( when ) 테스트 하고자하는 대상을 실제로 실행 시킵니다.
( then ) 어떤 특정한 행동(테스트 대상 실행) 때문에 발생할거라고 예상되는 결과에 대해 예측하고 맞는 지 확인합니다.
지금 까지 사용한 애너테이션 말고도 jUnit5 에서 제공 되는 애너테이션이 엄청 많이 있다 .
https://docs.junit.org/current/user-guide/#writing-tests-annotations
JUnit 5 User Guide
Although the JUnit Jupiter programming model and extension model do not support JUnit 4 features such as Rules and Runners natively, it is not expected that source code maintainers will need to update all of their existing tests, test extensions, and custo
docs.junit.org
가이드를 확인해서 한번 확인해보는 것도 좋다.
Mockito란 무엇일까?
서비를 개발하면서 서비스 계층에 있는 기능들을 테스트 하려고 할 때, 주입 받아오는 여러가지 repository를 어떻게 처리할 지 궁금증이 생긴다. 테스트에서는 해당 기능이 정상적으로 잘 작동되는지 확인만 하면 되는데 findById()와 같이 이런 것이 잘 받아오는 것이 중요하지 않다라는 얘기다.
이럴 때 테스트에서 사용할 수 있게 Mock Object 이라는 것을 제공을 해주고, 가짜 객체라는 뜻을 얘기한다.
자바에서는 이런 환경을 구성할 수 있게 Mockito라는 것을 지원해준다.
@Mock 애너테이션을 사용하기 위해서는 테스트 클래스에 @ExtendWith(MockitoExtension.class)를 추가해줘야 한다.
이상적으로, 각 테스트 케이스는 서로 분리되어야 한다. 이를 위해 가짜 객체(Mock Object)를 생성하는 방법을 알아보았고,
사용하는 곳은 분리 되기 어려운 클래스들에서 사용이 된다.
예를 들어 Controller 클래스만 테스트를 진행하고 싶을때 분리 되기 어려운 것들이 Controller, Service, Repository
Service 클래스에서는 Service, Repository 그리고 Repository 클래스에서는 Repository들이 분리되기가 어렵다
Mock Object 를 사용한다고 하여 실제 DB작업은 하지 않는다는 것이 중요하다. 말 그대로 실제 객체와 겉만 같은 객체이다.
무언가를 주입을 해주고 객체를 던져주어야 할 것이 있다면 given 이라는 메서드를 사용해야 한다

productRepository 에서 해당하는 id값을 찾아와 product 객체에 넣어줘야 하는데 이 부분을 given 으로 넣어줘야 한다

productId 를 찾아와서 Optional타입으로 product를 주입해준다
통합 테스트란 무엇일까?
단위 테스트 (Unit Test) 는 하나의 모듈이나 클래스에 대해 세밀한 부분까지 테스트가 가능한 테스트이다.
하지만 모듈 간에 상호 작용 검증은 할 수 없다는 점이 있다.
통합 테스트 (Integration Test) 는 두 개 이상의 모듈이 연결된 상태를 테스트할 수 있습니다.
모듈 간의 연결에서 발생하는 에러 검증이 가능합니다.
📒 Spring Boot를 이용한 통합 테스트
통합 테스트는 여러 단위 테스트를 하나의 통합된 테스트로 진행합니다.
@SpringBootTest
스프링이 동작되도록 해주는 애너테이션이며, Spring IoC/DI 기능이 사용됩니다.
그리고 Repository 를 사용하여 DB CRUD가 가능해집니다.
테스트 코드에서 선언한 필드 변수들은 기본적으로 공유가 되지 않는다.
그러나 @TestInstance(TestInstance.Lifecycle.PER_CLASS)를 테스트 클래스 위에 선언하게 되면
필드 변수들 또한 공유할 수 있게 해준다.
CSRF 공격에 대한 방어를 disable 하는 이유
Jwt를 사용하는 스프링 부트 프로젝트에서는 시큐리티 설정 부분에서 csrf 설정이 disable 되어 있는 프로젝트가 많을 것이다.
갑자기 문득 생각이 들었다 csrf 공격은 위험한 공격이라 필수적으로 막아줘야 하지 않을까? 라는 생각이 들었다.
구글링과 열심히 자료를 찾아본 결과로
로그인을 세션 방식을 사용하는 경우에는 세션이 고정되어 있기 때문에 csrf 공격에 대한 방어가 필수적이지만
jwt token 을 사용하는 경우에는 세션이 stateless 상태로 있기 때문에 csrf 공격에 대한 방어가 필수적이지 않다고 한다.
JWT 탄생한 이유
JWT를 알기 전에 세션에 대해서 알아야 하지만 여기서는 간략하게 알아보고 후에 JWT 탄생 이유에 대해서 세션과 함께 정리하는 글을 다시 업로드할 예정이다.
우선 세션 기반 인증 방식의 한계를 극복하고 HTTP의 state-less(무상태) 특성을 효과적으로 지원하며, 서버 확장성과 분산 환경에서의 효율성을 높이기 위해 탄생했다고 한다.
세션 방식은 사용자의 인증 정보를 서버에 저장해야 하는 부담이 있지만, JWT는 토큰 자체에 인증 정보가 포함 되어 서버가 추가 저장을 하지 않고도 인증이 가능하며, 이는 RESTful 서비스 환경에 적합하다고 한다.
세션 기반 인증의 한계점은
서버 부하랑 분산 환경의 어려움이 있는데
서버 부하 - 사용자의 인증 정보를 서버에 저장해야 하므로, 대규모 사용자나 분산된 환경에서 서버의 메모리 및 저장 공간에 부담을 준다고 한다.
분산 환경의 어려움 - 여러 서버로 분산된 서비스에서는 각 서버마다 세션 정보를 공유하거나 관리해야 하므로 복잡성이 증가한다.
JWT는 HTTP가 기본적으로 stateless 프로토콜이지만 이러한 특성에 맞춰 서버가 상태를 저장하지 않고도 인증을 처리할 수 있게 도와준다.
서버가 클라이언트의 인증 정보를 저장할 필요가 없기 때문에 서버를 쉽게 확장하고, 더 많은 트래픽을 처리할 수 있게 된다.
헤더, 페이로드, 서명의 세 부분으로 구성되며 서명 과정을 통해 내용의 위변조를 방지하고 신뢰성을 보장한다.
'TIL & STUDY' 카테고리의 다른 글
| Daily Study : 6 (1) | 2025.09.22 |
|---|---|
| Daily Study : 5 (0) | 2025.09.20 |
| Daily Study : 4 (0) | 2025.09.19 |
| Daily Study : 2 (2) | 2025.09.17 |
| Daily Study : 1 (0) | 2025.09.16 |