459. Dummy (더미) - 인자 채우기용, 실제 사용 안됨

핵심 인사이트 (3줄 요약)

  1. 본질: 더미(Dummy) 객체는 테스트 더블(Test Double)의 가장 원시적인 형태로, 메서드 호출에 필요한 파라미터 개수를 맞추어 컴파일 에러를 방지할 목적(인자 채우기용)으로만 존재하며, 내부 로직에서 절대 실제로 사용(호출)되지 않는 깡통 객체다.
  2. 가치: "이 테스트 시나리오에서는 이 객체가 전혀 중요하지 않다"는 의도를 동료 개발자에게 코드로 명확하게 전달하여, 불필요한 테스트 데이터 세팅에 들어가는 인지적 부하(가독성 파괴)를 막아준다.
  3. 융합: null을 던지거나 익명 클래스로 대충 껍데기만 만들어 던지는 방식으로 구현되며, 객체지향의 의존성 주입(DI) 아키텍처 환경에서 불필요한 결합을 임시로 끊어내는 가장 가벼운 테스트용 땜질 도구다.

Ⅰ. 개요 및 필요성 (Context & Necessity)

  • 개념: Dummy는 문자 그대로 '마네킹, 가짜'를 뜻한다. 테스트 코드를 짤 때 OrderService를 생성하려면 new OrderService(user, product, db) 처럼 3개의 객체를 넣어야 한다. 그런데 이번 테스트는 'product'만 검증하는 상황이다. 이때 'user'와 'db' 자리에 억지로 복잡한 진짜 객체를 생성해서 넣는 대신, 아무 기능도 없는 텅 빈 new DummyUser()를 끼워 넣어 문법(컴파일)만 만족시키는 것이다.

  • 필요성: 만약 Dummy를 쓰지 않고 진짜 User 객체를 만든다면? User 객체를 만들기 위해 이름, 나이, 주소, 핸드폰 번호를 세팅하는 코드 10줄을 짜야 한다. 정작 이 테스트에서는 User 객체를 단 한 번도 안 쓰는데 말이다! 코드를 읽는 리뷰어는 "어? 이 테스트에서 User의 주소가 중요한 역할을 하나?"라고 심각하게 착각하게 된다(테스트 가독성 파괴). Dummy는 이 불필요한 '맥락의 오염'을 막고, 테스트를 가볍게 유지하기 위해 반드시 필요하다.

  • 💡 비유: Dummy는 **'드라마 세트장의 마네킹 엑스트라'**와 같습니다. 카메라 초점은 주인공(테스트 대상)에게 맞춰져 있습니다. 뒤에 흐릿하게 보이는 카페 손님 10명은 대사를 할 일도 없고, 얼굴이 자세히 보이지도 않습니다. 굳이 비싼 몸값의 진짜 배우 10명을 고용할 필요 없이, 플라스틱 마네킹(Dummy)에 옷만 입혀서 자리에 앉혀두기만(파라미터 채우기) 하면 영화(컴파일)는 완벽하게 찍힙니다.

  • 등장 배경 및 발전 과정:

    1. 컴파일러의 깐깐함: C++나 Java 같은 강타입(Strongly Typed) 언어는 함수 인자를 빈칸으로 두면 컴파일조차 안 되었다.
    2. Null의 남용과 한계: 개발자들은 깡통 자리에 null을 넣기 시작했다(new OrderService(null, product, null)). 하지만 null은 나중에 실수로 로직이 닿았을 때 NullPointerException이라는 모호한 에러를 뿜어 디버깅을 지옥으로 만들었다.
    3. 명시적 Dummy 패턴 등장: "호출되는 순간 '이건 더미야! 부르지 마!'라고 친절하게 예외(Exception)를 던지는 가짜 객체를 만들자"라는 것이 xUnit 패턴으로 정립되었다.
  • 📢 섹션 요약 비유: Dummy는 교통사고 충돌 테스트 차량의 **'뒷좌석 플라스틱 인형'**입니다. 앞좌석 에어백 테스트가 목적이기 때문에, 뒷좌석에는 진짜 사람은커녕 비싼 센서가 달린 더미도 필요 없습니다. 그냥 무게만 맞추는(파라미터 개수) 싼 플라스틱 인형을 앉혀두는 것입니다.


Ⅱ. 아키텍처 및 핵심 원리 (Deep Dive)

1. Dummy 객체의 3가지 구현 아키텍처

테스트 코드에서 Dummy를 주입하는 3가지 진화 단계다.

[ 1단계: 가장 무식한 Null 주입 ]

// 컴파일은 통과하지만, 나중에 어디서 죽었는지 파악이 힘들다.
orderService.createOrder(null, product, null);

[ 2단계: 명시적 인터페이스 구현 (정석) ]

// 개발자가 직접 빈 깡통 클래스를 만든다. 
// 만약 로직이 실수로 이 객체를 건드리면 명확한 에러를 터뜨리게 방어벽을 친다.
public class DummyUser implements User {
    public String getName() {
        throw new RuntimeException("이건 더미 객체입니다. 호출하면 안 됩니다!");
    }
}
// 테스트 코드 적용
orderService.createOrder(new DummyUser(), product, new DummyDB());

[ 3단계: Mockito 라이브러리 활용 (현대) ]

// 클래스를 만들 필요 없이 프레임워크가 1초 만에 깡통을 찍어준다.
User dummyUser = mock(User.class); // Mockito를 이용해 더미를 생성
orderService.createOrder(dummyUser, product, dummyDb);

2. Dummy와 다른 테스트 더블의 차이점 (핵심)

  • Dummy vs Stub: Stub은 테스트 과정에서 실제로 호출되며, 특정 값(예: "100원")을 대답해야 한다. 반면 Dummy는 테스트 끝날 때까지 단 한 번도 호출되어서는 안 된다. 만약 호출되면 그 테스트는 잘못 짠 것이다.

  • 📢 섹션 요약 비유: 은행 강도 영화를 찍는데, 강도(테스트 객체)가 은행원(Stub)에게 총을 겨누면 은행원은 "돈 여기 있습니다(특정 리턴값)"라고 대사를 쳐야 합니다. 반면 은행 구석에 엎드려 있는 손님(Dummy)은 그냥 자리만 지킬 뿐, 강도가 굳이 손님에게 다가가서 말을 걸면 대본(테스트 로직)이 꼬여버린 겁니다.


Ⅲ. 융합 비교 및 다각도 분석

1. 테스트 픽스처(Test Fixture)로서의 Dummy

척도진짜 객체 (Real Object) 주입더미 (Dummy Object) 주입
구현 비용이름, 나이, 주소 등 10개 필드 다 채워야 함 (10줄)깡통 객체 생성 1줄이면 끝남
의도 전달력리뷰어가 "이 값들이 중요한가?" 고민함 (가독성 하락)리뷰어가 "아, 이 객체는 이 테스트에서 안 쓰이네!" 즉각 인지
테스트 결합도User 클래스 구조 바뀌면 테스트 코드 다 박살남깡통이라 User 내부가 바뀌든 말든 영향 0%
용도복잡한 도메인 모델 검증 시오직 메서드 서명(Signature) 만족용

과목 융합 관점

  • 소프트웨어 공학 (리팩토링, Refactoring): 레거시 코드는 보통 1개의 함수가 파라미터를 10개씩 받는다(안티패턴). 이런 함수를 테스트하려면 Dummy를 9개나 만들어서 쑤셔 넣어야 한다. 테스트 코드를 짜다 보면 "내가 왜 이 짓을 하고 있지? 파라미터가 10개나 되는 함수 구조가 썩은 거 아니야?"라는 깨달음(Code Smell)을 얻게 된다. 즉, Dummy를 너무 많이 만들어야 하는 고통 자체가, 코드를 작은 단위로 찢어야 한다는 리팩토링의 신호등 역할을 융합적으로 수행한다.

  • 클린 아키텍처 (Clean Code): 클린 코드에서는 테스트 코드의 '가독성(Readability)'을 프로덕션 코드만큼 중요하게 여긴다. Dummy를 활용한 코드는 소음(Noise)의 제거다. 본질이 아닌 객체 생성 코드 50줄을 지워버림으로써, 테스트 코드가 마치 깔끔한 영어 소설처럼 진짜 중요한 핵심 로직(Assert)만 부각되도록 아키텍처의 투명성을 끌어올린다.

  • 📢 섹션 요약 비유: 진짜 객체를 쓰는 것은, 수학 문제 "1+1=?"을 푸는데 굳이 순금으로 만든 화려한 연필을 꺼내서 적는 것과 같습니다. 계산(테스트) 결과에는 아무 영향이 없는데 연필(객체)을 구하느라 돈과 에너지를 너무 많이 썼습니다. Dummy는 그냥 굴러다니는 100원짜리 몽당연필입니다. 본질인 계산(1+1)에만 100% 에너지를 집중하게 해주는 효율적인 도구입니다.


Ⅳ. 실무 적용 및 기술사적 판단

실무 시나리오

  1. 시나리오 — 의미 없는 데이터 팩토리(Factory)의 저주: 백엔드 팀이 테스트 코드를 짠다. 그런데 Order 객체를 하나 만들려면, 그 안의 User, Store, Payment 객체를 다 진짜로 만들어야 했다. 개발자들은 귀찮아서 TestObjectFactory.createFullOrder() 라는 거대한 만능 로봇을 만들어, 무조건 속이 꽉 찬 진짜 객체를 찍어내어 테스트에 넣었다. 결과적으로 테스트 코드 하나 돌리는데 메모리를 수백 메가(MB)씩 퍼먹고 5초나 걸렸다.

    • 아키텍트의 해결책: 과도한 픽스처(Fixture) 세팅에 의한 자원 낭비다. 할인율 로직을 테스트하는데 왜 User의 '주소'와 '핸드폰 번호' 정보가 꽉 찬 객체가 필요한가? 아키텍트는 "이 테스트에서 안 털어보는(Not Asserted) 데이터는 모조리 Dummynull로 비워라"라고 지시해야 한다. 꽉 찬 가짜 객체를 무지성으로 찍어내면 테스트는 무거워지고, 나중에 DB 구조 하나만 바뀌어도 팩토리 클래스 전체가 폭발하는 유지보수 지옥이 열린다.
  2. 시나리오 — Null 주입이 부른 폭탄 돌리기: 주니어 개발자가 파라미터를 맞추기 위해 calculate(500, null, null) 이라고 쿨하게 널(Null)을 주입했다. 처음엔 잘 돌았다. 6개월 뒤, 다른 개발자가 calculate 함수 내부에 "두 번째 파라미터를 살짝 검사하는 로직"을 1줄 추가했다. 그 순간 전 세계 500개의 테스트가 일제히 NullPointerException을 토하며 전멸했다. Null이 터지는 곳이 테스트 파일인지 원본 소스인지 디버깅하느라 하루를 날렸다.

    • 아키텍트의 해결책: Null은 가장 멍청한 Dummy다. Null은 자기가 왜 불렸는지, 누가 잘못 불렀는지 아무 말도 안 하고 그냥 죽어버린다. 아키텍트는 테스트 코드에서 명시적으로 Dummy 객체를 생성해서 주입하게 강제해야 한다. 명시적 Dummy는 실수로 호출되었을 때 throw new RuntimeException("이봐, 난 더미야! 날 부른 당신의 소스코드 로직이 꼬였어!") 라고 친절하게 에러의 원인(Root Cause)을 외치며 죽기 때문에, 1초 만에 테스트 로직의 꼬임을 디버깅할 수 있다.

도입 체크리스트

  • 기술적: Mockito의 @Mock을 무의미한 더미용으로 남발하고 있지 않은가? @Mock을 쓰면 리플렉션 흑마법을 쓰기 때문에 깡통 더미(new Dummy())를 직접 만드는 것보다 테스트 속도가 살짝 느려진다. 아무 기능도 안 하는 자리 채우기용 객체라면, 굳이 프레임워크의 무거운 마법(Mock)을 빌리지 말고 순수 자바 객체로 빈 깡통 클래스를 하나 뚝딱 만들어서 주입하는 것이 더 우아하고 빠를 수 있다.
  • 설계적: 의도적인 네이밍(Naming) 규칙이 있는가? 코드를 읽을 때 변수명이 User u = new User() 이면 리뷰어가 헷갈린다. 반드시 User dummyUser = new DummyUser() 처럼 변수명 자체에 '이건 깡통이야'라는 꼬리표(Naming Convention)를 대문짝만하게 박아두어야 테스트 코드의 오독(Misreading)을 막을 수 있다.

안티패턴

  • 스마트 더미 (Smart Dummy): 더미는 바보여야 한다. 그런데 더미 객체 안에 "혹시 모르니까 이름은 '김철수'로 세팅해놓고, 나이는 '20'을 리턴하게 짜둘까?"라며 쓸데없는 짱구를 굴리는 안티패턴. 이러면 이건 더미가 아니라 '스텁(Stub)'이 되어버린다. 나중에 다른 개발자가 이 깡통을 진짜 데이터가 들어있는 객체로 착각하고 로직에 가져다 쓰게 되면서 거대한 똥 밭이 열린다. "더미는 불리면 무조건 즉사(Exception)해야 한다."

  • 📢 섹션 요약 비유: 더미 객체에 몰래 데이터를 채워놓는 것은, 마네킹 배 속에 진짜 사람 내장을 넣어놓는 미친 짓과 같습니다. 마네킹은 텅 비어있어야 가볍고 치우기 편합니다. 마네킹이 피를 흘리면(로직을 수행하면) 촬영장(테스트) 전체가 공포와 혼란(디버깅 지옥)에 빠집니다.


Ⅴ. 기대효과 및 결론

정량/정성 기대효과

구분자리 채우기용으로 진짜 객체를 무겁게 주입 (AS-IS)깡통 더미(Dummy) 객체를 명시적 주입 (TO-BE)개선 효과
정량진짜 객체 10개 초기화 세팅 코드 50줄 작성new Dummy() 1줄로 처리 완료테스트 코드 작성 리드타임 및 라인 수 80% 다이어트
정량무거운 연관 객체 다 띄우느라 테스트 1개당 1초 소요텅 빈 메모리로 0.001초 컷 달성전체 단위 테스트 슈트 실행 속도 99% 향상
정성"이 수많은 데이터 중 뭐가 진짜 핵심이지?" 혼란"아, 이 테스트는 오직 상품(Product)만 검사하네!" 직관테스트 코드의 투명성(Clarity) 확보 및 코드 리뷰 시간 단축

미래 전망

  • 언어 차원의 묵인(Omission) 문법 지원: 자바(Java) 같은 구식 언어는 파라미터를 다 안 채우면 컴파일이 멈춰서 억지로 Dummy를 만들어 끼워야 했다. 하지만 코틀린(Kotlin)이나 타입스크립트(TypeScript) 같은 현대 언어는 파라미터에 '기본값(Default Value)'을 설정하거나, 내가 원하는 인자만 골라 넣는 '네임드 파라미터(Named Parameter)' 문법을 지원한다. 이를 통해 언어 자체가 Dummy 패턴의 억지스러움을 문법 레벨에서 박살 내고 소멸시켜 가는 추세다.
  • AI 픽스처(Fixture) 자동 주입: 깃허브 코파일럿(Copilot)이 등장하며, 테스트를 짤 때 내가 검증하려는 타겟만 적어두면, 나머지 빈칸(파라미터)은 AI가 "아, 얘네는 이번 테스트에서 안 쓰이니까 깡통(Dummy)으로 채워둘게"라며 1초 만에 껍데기를 다 타이핑해 주는 오토-더미 시대로 넘어가고 있다.

참고 표준

  • xUnit Test Patterns의 Dummy Object 정의: 제라드 메스자로스가 정의한 "테스트에 전달되긴 하지만 절대로 사용되지 않는 객체. 오직 파라미터 목록을 채우는 용도로만 쓰이는 것"이라는 절대 표준.
  • Null Object Pattern (디자인 패턴): 더미와 맞닿아 있는 객체지향 패턴. null을 리턴해서 NullPointerException을 터뜨리게 놔두지 말고, 텅 빈 깡통 객체(Null Object)를 리턴하게 만들어 시스템이 뻗지 않고 조용히 넘어가게 만드는 방어적 아키텍처.

테스트 더블의 첫 번째 엑스트라, 더미(Dummy)는 소프트웨어 테스팅의 **'미니멀리즘(Minimalism)'**을 상징한다. 우리는 코드를 짤 때 불안함 때문에 자꾸 모든 것을 진짜처럼 세팅하고 꽉꽉 채워 넣으려(Over-specifying) 한다. 하지만 진짜 위대한 아키텍트는 "이 상황에서 본질이 아닌 것은 과감히 쓰레기(Dummy) 취급하고 비워버리는 결단력"을 보여준다. 진짜로 털어봐야 할 1%의 핵심 로직을 돋보이게 하기 위해, 나머지 99%의 주변 환경을 플라스틱 마네킹으로 도배해 버리는 무자비한 생략의 기술, 그것이 Dummy가 가져다주는 투명한 테스트 아키텍처의 시작이다.

  • 📢 섹션 요약 비유: Dummy를 세우는 것은, 명품 가방 사진을 찍을 때 **'아무 무늬 없는 흰색 배경지(호리존)'**를 깔아두는 것과 같습니다. 배경에 화려한 꽃이나 사람(진짜 객체)을 두면 시선이 분산됩니다. 가방(테스트 타겟) 하나만 완벽하게 빛나게 만들기 위해, 배경은 가장 바보 같고 존재감 없는 깡통(Dummy)으로 비워두는 최고의 사진술(테스팅 기법)입니다.

📌 관련 개념 맵 (Knowledge Graph)

개념 명칭관계 및 시너지 설명
테스트 더블 (Test Double)영화 촬영장의 스턴트맨을 통칭하는 단어. Dummy는 그중에서도 가장 싼 몸값을 자랑하며 가만히 서있기만 하는 1번 마네킹 배우. (이전 장 458번)
스텁 (Stub)Dummy가 "난 아무것도 안 해!" 라면, Stub은 한 단계 진화해서 "네가 나를 찌르면 나는 무조건 100을 줄게!"라고 응답값을 세팅해 놓은 로봇 자판기. (다음 장 460번)
의존성 주입 (DI)Dummy라는 플라스틱 인형을 진짜 시스템의 배때지에 꽂아 넣을 수 있게 허락해 주는 유일한 객체지향의 마법 나사못.
테스트 픽스처 (Test Fixture)테스트를 하기 전 링 위를 세팅하는 과정. 이때 진짜 도구로 링을 다 채우면 무거워지니, Dummy를 적절히 섞어 링을 가볍게 세팅해야 한다.
메서드 서명 (Method Signature)함수 이름과 파라미터 갯수, 타입을 뜻함. Dummy는 오직 이 컴파일러의 '깐깐한 룰(서명)'을 통과하기 위한 여권(Passport) 역할만 한다.

👶 어린이를 위한 3줄 비유 설명

  1. 내가 '장난감 자동차 바퀴가 잘 굴러가는지'만 검사하고 싶은데, 자동차를 조립하려면 무조건 로봇 조종사를 태워야만 문이 닫히는 규칙(컴파일)이 있었어요.
  2. 바퀴만 보면 되니까 비싸고 무거운 진짜 로봇 조종사를 데려올 필요 없잖아요? 그래서 조종석에 **엄청 가볍고 싼 '플라스틱 찰흙 인형'**을 대충 구겨 넣었어요.
  3. 이렇게 테스트에 꼭 필요하진 않지만, 빈칸을 남겨두면 안 돼서 어쩔 수 없이 자리만 채우려고 던져두는 가짜 깡통 인형을 **'더미(Dummy)'**라고 한답니다!