RECENT POSTS

최근에 작성한 글

01 / 03

전체 글

전체 보기

[TIL] SpringBoot 심화(1)-소셜 로그인(OAuth), 테스트, AOP, 예외처리

오늘은 카카오 소셜 로그인, 테스트 코드(Unit Test, Integration Test, Mockito), Spring AOP, 예외 처리까지 Spring 백엔드에서 자주 사용하는 핵심 기능들을 공부했다.


1. OAuth와 소셜 로그인

기존 회원가입 방식은 서비스마다 아이디와 비밀번호를 생성해야 하고, 서비스 운영자는 개인정보를 직접 관리해야 하는 부담이 있다.

 

이러한 문제를 해결하기 위해 OAuth가 등장했다.

 

OAuth는 사용자의 비밀번호를 서비스에 전달하지 않고도 인증을 위임할 수 있는 표준 프로토콜이다. 대표적으로 Google, Kakao, Naver 로그인이 OAuth 기반으로 동작한다.


OAuth 로그인 흐름

[OAuth의 핵심]

  • 비밀번호를 직접 받지 않는다.
  • 인가 코드(Code)를 이용해 Access Token을 발급받는다.
  • Access Token으로 사용자 정보를 조회한다.

2. 단위 테스트(Unit Test)

서비스 규모가 커질수록 버그를 늦게 발견할수록 수정 비용은 기하급수적으로 증가한다.

단위 테스트는 작은 기능 단위로 검증하여 버그를 조기에 발견하기 위한 테스트이다.


[ JUnit ]

@BeforeEach

각 테스트 전에 실행

@BeforeEach
void setUp() {

}

@AfterEach

각 테스트 후 실행

@AfterEach
void tearDown() {

}

@BeforeAll

모든 테스트 시작 전 1회 실행

@BeforeAll
static void beforeAll() {

}

@AfterAll

모든 테스트 종료 후 1회 실행

@AfterAll
static void afterAll() {

}

3. Mockito

Service를 테스트할 때는 Repository가 필요하다.

하지만 실제 DB를 사용하면 테스트 속도가 느려지고 독립적인 테스트가 어렵다.

Mockito는 가짜(Mock) 객체를 만들어 의존성을 대체하는 테스트 프레임워크이다. 서비스 로직만 독립적으로 검증할 수 있도록 도와준다.

예시

when(productRepository.findById(id))
    .thenReturn(Optional.of(product));

이렇게 하면 실제 DB 대신 원하는 값을 반환하도록 설정할 수 있다.


4. 통합 테스트

단위 테스트는 하나의 클래스만 검증한다.

하지만 실제 서비스는

Controller
    ↓
Service
    ↓
Repository
    ↓
DB

가 함께 동작한다.

통합 테스트는 여러 계층을 함께 실행하여 실제 서비스와 비슷한 환경을 검증한다.

Spring에서는

@SpringBootTest

를 사용하면 Spring Context를 띄운 상태에서 테스트할 수 있다.


5. Controller 테스트

Controller는 HTTP 요청과 응답을 처리하는 계층이다.

Spring에서는

MockMvc

를 이용해 실제 서버를 실행하지 않고도 HTTP 요청을 테스트할 수 있다.

이를 통해

  • GET
  • POST
  • PUT
  • DELETE

API가 정상적으로 동작하는지 쉽게 검증할 수 있다.


6. Spring AOP

AOP(Aspect Oriented Programming)는 공통 기능을 핵심 로직과 분리하는 기술이다.

예를 들어

  • 로그
  • 실행시간 측정
  • 권한 검사
  • 트랜잭션

같은 기능은 여러 곳에서 반복된다.

AOP를 사용하면

핵심 로직

회원가입
상품조회
주문

에

로그 출력

실행시간 측정

예외 처리

같은 부가 기능을 공통적으로 적용할 수 있다.

대표적인 Advice

@Before

실행 전

@After

실행 후

@Around

실행 전후


7. API 수행시간 측정

실습에서는 AOP를 이용하여

회원별 API 사용 시간을 기록하는 기능도 구현했다.

API 요청

↓

Controller 진입

↓

Business Logic

↓

응답

↓

수행시간 저장

이렇게 요청부터 응답까지 걸린 시간을 측정하여 회원별 사용 시간을 누적할 수 있다.


8. API 예외 처리

예외 처리는 단순히 오류를 막는 것이 아니라

클라이언트에게 정확한 HTTP 상태 코드와 메시지를 전달하는 것이 중요하다.

대표적인 상태 코드는

상태 코드의미

200 성공
400 잘못된 요청
401 인증 실패
403 권한 없음
404 리소스 없음
500 서버 오류

Spring에서는

HttpStatus.BAD_REQUEST

처럼 enum 형태로 사용할 수 있다.


9. Global Exception

Controller마다

try {

} catch {

}

를 작성하면 중복 코드가 계속 생긴다.

Spring에서는

@RestControllerAdvice

를 이용해 모든 Controller의 예외를 한 곳에서 처리할 수 있다.

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(IllegalArgumentException.class)
    public ResponseEntity<?> handleException(
            IllegalArgumentException e) {

    }

}

이 방식은 예외 처리 로직을 중앙에서 관리할 수 있어 유지보수성과 재사용성을 높여준다.


10. properties를 이용한 에러 메시지 관리

예외 메시지를 코드에 직접 작성하면

throw new IllegalArgumentException("상품이 없습니다.");

수정이 어렵고 중복도 발생한다.

Spring에서는

not.found.product=해당 상품이 존재하지 않습니다.
below.min.my.price=최저 희망가는 최소 {0}원 이상입니다.

처럼 messages.properties에 메시지를 정의하고 MessageSource를 통해 가져와 사용할 수 있다. 이를 통해 메시지를 중앙에서 관리하고 다국어 지원도 가능해진다.


 Spring에서 단순히 기능을 구현하는 것을 넘어 유지보수성과 확장성을 고려한 개발 방식을 배웠다.

특히 OAuth 기반의 소셜 로그인 흐름과 사용자 정보 관리 방식을 이해했고, 테스트 코드를 통해 안정적인 코드를 작성하는 방법을 익혔다. 또한 AOP를 활용한 공통 기능 분리와 @RestControllerAdvice를 이용한 전역 예외 처리, MessageSource를 통한 에러 메시지 관리까지 학습하면서 Spring이 제공하는 다양한 생산성 향상 기능을 경험할 수 있었다.