목

Mock

도구

테스트를 돌릴 때 진짜 부품 대신 끼워 넣어 정해진 답만 돌려주게 만든 가짜 객체입니다.

등장 배경

테스트는 코드가 의도대로 도는지 기계가 대신 확인하게 만드는 일입니다. 확인하려는 코드가 자기 혼자 계산만 한다면 값을 넣고 결과를 보면 끝나지만, 실제 코드는 대개 바깥에 기댑니다. 결제 코드는 카드사에 요청을 보내고, 알림 코드는 메일 서버를 부르고, 목록 코드는 데이터베이스에서 값을 꺼냅니다.

이 바깥까지 그대로 두고 테스트를 돌리면 세 가지가 한꺼번에 따라옵니다. 한 건에 몇 초씩 걸려 느려지고, 남의 서비스에 실제 요청이 나가 돈이 들거나 진짜 결제가 일어나고, 그쪽이 점검 중이면 내 코드가 멀쩡해도 테스트가 실패합니다.

금요일 오후에 이런 장면이 나옵니다. 코드를 합칠 때마다 자동으로 도는 검사가 빨간불이 떠서 태오가 30분을 들여 원인을 찾았는데, 바뀐 코드에는 문제가 없고 결제사 테스트 서버가 점검 중이었습니다. 다음 주 월요일에 같은 일이 또 일어나면 팀은 그 테스트를 아예 꺼 버립니다.

목은 이 연결을 끊으려고 만든 물건입니다. 진짜 결제사 대신 "성공" 이라고만 답하는 가짜를 그 자리에 꽂아 두면, 테스트는 남의 서버가 아니라 내 코드만 확인하게 됩니다.

해결하는 문제

통제할 수 없는 것에 테스트가 기대는 상황을 끊어 냅니다. 구체적으로는 네 가지입니다.

  1. 속도 — 진짜 요청 한 번에 2초가 걸린다면 그 코드를 쓰는 테스트 300개는 10분입니다. 목으로 바꾸면 응답이 메모리에서 바로 나와 전체가 몇 초로 줄고, 그래야 개발자가 코드를 고칠 때마다 돌리게 됩니다.
  2. 비용과 부작용 — 결제 테스트를 돌릴 때마다 실제 승인이 나가면 안 됩니다. 메일도 같습니다. 알림 코드를 100번 테스트하는 동안 고객 주소로 메일 100통이 나가는 일을 막습니다.
  3. 안정성 — 남의 서버가 점검 중이거나 느릴 때 내 테스트가 빨간불이 되면, 팀은 빨간불을 보고도 그냥 다시 돌리는 습관이 듭니다. 플레이키 테스트라고 부르는 상태이고, 이게 늘어나면 테스트는 경고 기능을 잃습니다.
  4. 재현하기 어려운 상황 — 한도 초과, 응답이 10초 넘게 안 오는 상황, 카드사 장애는 실제로 만들기가 어렵습니다. 목은 그런 응답을 골라 돌려주게 만들 수 있어서, 잘 안 되는 경우의 코드를 확인할 수 있는 거의 유일한 수단입니다.

여기에 하나가 더 붙습니다. 목은 답을 돌려줄 뿐 아니라 자기가 어떻게 불렸는지 기억합니다. 결제가 두 번 눌렸을 때 카드사에 요청이 한 번만 나갔는지 같은 것은 결과값으로는 확인되지 않고, 목에게 "몇 번 불렸냐" 고 물어야 알 수 있습니다.

대안

목이 늘 최선은 아니라서 같은 문제를 다루는 수단이 넷 더 있습니다. 무엇을 고를지는 잘라 내려는 것이 속도인지 부작용인지에 따라 갈립니다.

  1. 샌드박스 — 상대가 제공하는 시험용 환경에 진짜로 요청을 보냅니다. 카드사가 주는 시험용 카드 번호를 쓰면 실제 돈은 안 나가면서 진짜 응답을 받습니다. 느리지만 주고받는 모양이 실제와 어긋나지 않아, 연동이 맞는지 보는 테스트는 이쪽을 씁니다.
  2. 가짜 구현체 — 흉내만 내는 게 아니라 간단하게 실제로 동작하는 것을 따로 만듭니다. 데이터베이스 대신 메모리에 값을 넣었다 꺼내는 작은 저장소가 그런 예입니다. 목보다 만드는 값이 크지만 여러 테스트가 함께 씁니다.
  3. 픽스처 — 미리 깔아 두는 상태와 데이터입니다. 문제가 바깥 연결이 아니라 준비 과정이라면 목이 아니라 이쪽입니다.
  4. 녹화와 재생 — 진짜 응답을 한 번 받아 파일로 저장해 두고 다음부터 그 파일을 씁니다. 목보다 실제에 가깝지만, 상대가 응답 모양을 바꾸면 저장해 둔 파일이 낡은 채로 남습니다.

선택 기준은 하나로 정리됩니다. 안쪽 코드 하나만 떼어 보는 단위 테스트에서는 목을 쓰고, 이어 붙인 상태가 실제로 맞물리는지 보는 자리에서는 진짜에 가까운 쪽을 씁니다. 둘 중 하나만 두면 빠른데 못 믿거나, 믿을 만한데 아무도 안 돌리는 상태가 됩니다.

실무 용례

"이 테스트 결제사 목으로 바꿔 주세요. 남의 서버 점검 때문에 우리 검사가 빨간불이에요."

내 코드 문제가 아닌 이유로 실패하고 있으니 바깥 연결을 끊자는 제안입니다.

"한도 초과는 목으로만 만들 수 있어요. 실제로 재현하려면 카드를 한도까지 채워야 해요."

실제로 일으키기 어려운 상황이라 가짜로 만들어 확인하겠다는 뜻입니다.

"목을 너무 많이 붙여서 이 테스트가 뭘 확인하는 건지 모르겠어요."

주변을 다 가짜로 바꾼 나머지 남은 검증이 의미를 잃었다는 지적입니다.

페이지덱이 유료 전환에 결제를 붙이던 때 태오가 처음 만든 것이 가짜 결제사였습니다. 승인 성공, 한도 초과, 카드 만료, 10초 뒤 응답 없음 네 가지를 돌려주게 해 두고 각각에 화면이 어떻게 되는지 확인했습니다. 실제 카드로는 첫 번째만 눌러 볼 수 있었고 나머지 셋은 만들 방법이 없었습니다.

문제는 반년 뒤에 생겼습니다. 결제사가 거절 응답의 형식을 바꿨는데 목은 옛 형식을 그대로 돌려주고 있어서, 검사는 계속 초록불인 채로 운영에서만 결제 실패 화면이 깨졌습니다. 지금 페이지덱은 목으로 도는 테스트와 별개로 샌드박스에 진짜 요청을 보내는 테스트를 하루 한 번 돌립니다.

흔한 오해

목을 많이 쓸수록 테스트가 좋아진다고 여기기 쉽습니다. 빨라지고 안 깨지니 지표만 보면 나아 보입니다. 그런데 목은 내가 상대의 동작을 이해한 대로 적어 둔 것이라, 그 이해가 틀렸거나 낡으면 테스트는 틀린 전제 위에서 초록불을 냅니다. 태오가 겪은 일이 정확히 이것입니다. 목이 늘어날수록 테스트 커버리지 숫자는 올라가는데 실제로 확인된 것은 줄어듭니다.

확인하려는 코드 주변을 전부 가짜로 바꾸는 것도 흔한 실수입니다. 하나만 남기고 다 끊어야 원인을 정확히 짚는다는 생각에서 나오는데, 그렇게 하면 테스트가 검증하는 것이 코드의 동작이 아니라 코드가 호출하는 순서가 됩니다. 구현을 조금만 고쳐도 동작은 그대로인데 테스트가 깨지고, 그런 일이 몇 번 반복되면 팀은 코드를 고칠 때마다 테스트부터 고치게 됩니다. 목은 통제할 수 없는 것만 끊는 자리에 씁니다.

자주 헷갈리는 용어

용어무엇인가목과의 차이
픽스처테스트를 돌리기 전에 미리 깔아 두는 상태와 데이터픽스처는 무대에 미리 놓아 두는 소품이고 목은 대사에 답하는 대역입니다. 픽스처는 "문서 세 건이 이미 있는 상태" 를 만들고, 목은 "결제 요청이 오면 성공이라고 답하라" 를 맡습니다

같이 보면 좋은 페이지

  • 테스트

    목이 어느 활동 안에서 쓰이는 도구인지 먼저 봅니다

  • 픽스처

    같은 준비 단계에서 짝으로 쓰이는 도구입니다

마지막 업데이트 2026-09-16