[Codeit]/Spring 백엔드 10기 위클리페이퍼

[10] 계층별 입력값 검증과 Mockito

uzlru 2026. 4. 6. 01:03

01. 계층별 입력값 검증의 범위와 책임

주로 상위 계층인 컨트롤러(Controller)에서 형식을 걸러내고, 하위 계층인 서비스(Service)와 엔티티(Entity)에서는 의미를 검증한다. 이러한 전략은 중복 검증을 방지할 뿐만 아니라, 핵심 비지니스 규칙을 하위 계층에서 한 번 더 보호함으로써 객체의 무결성을 보장하고 안정성을 확보한다.

 

계층 범위 책임  
컨트롤러
(Controller)
문법적 검증
(Syntactic validation)
값의 공백 / 형식 / 범위 등 검증 @Valid 및 Bean Validation 활용
서비스
(Service)
논리적 / 도메인 검증
(Semantic Validation)
시스템 상태와 관련된 검증 DB 조회가 필요한 비지니스 규칙
엔티티
(Entity)
객체의 무결성 보장 객체 유효성 검증

 

2. 트레이드오프

트레이드 오프(Trade-Off)란 어떤 요소의 질이나 양을 높이려고 할 떄, 반드시 연동된 다른 요소의 손실이 발생하는 상층 관계를 의미한다. 즉, A를 선택하면 B가 나빠지고 B를 선택하면 A가 나빠지는 구조를 뜻한다. 이러한 트레이드 오프는 서비스의 목적에 맞게 가장 적절한 지점을 찾을 때 사용한다.

 

검증에서의 트레이드 오프   장점 단점
엄격한 검증 모든 계층에서 중복 검증 안정성 극대화 코드 기하급수적 증가 / 성능 저하
느슨한 검증 각 계층별로 필요한 검증 성능 검증 로직 누락으로 인한 데이터 오염

 

 


 

2. Mockito

Mockito는 자바 애플리케이션의 단위 테스트(Unit Test)를 위해 사용하는 가장 대표적인 Moking Framwork를 의미한다. 즉, 테스트 하려는 객체가 의존하는 다른 객체들을 가짜(Mock)로 만들어, 외부 환경에 상관없이 특정 로직만 독립적으로 검증할 수 있게 도와주는 도구를 뜻한다. 이러한 가짜 객체를 활용하면 실제 DB나 외부 서비스 등이 없어도 테스트 하고자 하는 서비스 로직만 빠르고 정확하게 테스트하는 것이 가능해진다.

1. 핵심 개념

핵심 개념   에노테이션
가짜 객체
(Mock)
실제 객체처럼 동작하지만 내부 로직이 정의되지 않은 빈 껍데기로, 주로 행위를 검증 @Mock
상태 정의
(Stub)
가짜 객체의 특정 메서드가 호출되었을 때, 반환할 값을 미리 정해놓는 것  
일부 가짜 객체
(Spy)
실제 객체를 감싸서 만든 것으로, 기본적으로 실제 메서드를 호출하지만 일부 메서드는 빈 껍데기 @Spy

 

2. 상황별 선택


방식 구체적 예시
Mock + Stub 외부 결제 API를 호출하는 기능을 테스트할 때, 실제 결제를 일으키지 않고 성공 응답만 받도록 설정
외부 의존성이 복잡하거나 실제 DB / API 호출을 피해야 하는 경우
Mock (Verify) 메일 발송 서비스 테스트 시, 실제로 메일이 나갔는지보다는 sendEmail() 메서드가 1번 호출됐는지 확인
메서드의 호출 여부나 횟수가 비즈니스 로직의 핵심인 경우
Spy 실제 List 객체를 사용하면서 size() 메서드만 항상 100을 반환하게 만들고 싶을 때
외부 라이브러리나 레거시 코드를 사용하면서 특정 메서드만 가짜로 바꾸고 싶을 경우

 

3. 테스트 코드 작성 흐름

테스트 코드 흐름  
준비
(Given)
테스트에 필요한 가짜 객체 생성 / 동작 정의
실행
(When)
실제 테스트 하고자 하는 메서드 호출
검증
(Then)
결과값 검증