스마트 목(Smart Mock)은 엔드포인트 스키마를 읽어 몇 초 안에 그럴듯한 가짜 API 응답을 생성합니다. 실제 형식의 이메일, 합리적인 타임스탬프, 사람이 읽을 수 있는 이름 등을 반환하므로 대부분의 프런트엔드 작업을 바로 시작할 수 있습니다.
하지만 요청에 따라 응답을 분기해야 할 때는 스마트 목만으로 충분하지 않습니다. 예를 들어 /login은 알려진 사용자에게 200을, 다른 사용자에게 401을 반환해야 할 수 있습니다. /orders/{id}는 ID별로 배송됨·취소됨 상태를 반환해야 할 수도 있고, 오류 처리를 검증하려고 필요할 때 500을 강제해야 할 수도 있습니다.
이 글에서는 Apidog의 목 예상(Mock Expectations) 과 목 스크립트(Mock Scripts) 를 사용해 조건부 응답을 구현하는 방법을 다룹니다. 기본적인 목킹 흐름은 API 목킹 개요를 먼저 참고하세요. 계약 우선 방식의 배경은 OpenAPI Initiative에서 확인할 수 있습니다.
조건부 목킹이 실제로 의미하는 것
조건부 목은 다음 규칙으로 생각하면 됩니다.
요청이 특정 조건과 일치하면, 지정한 응답을 반환한다.
Apidog에서는 두 계층으로 응답을 제어합니다.
-
필드 수준 사용자 정의
- 응답 필드에 고정값 또는 Faker.js 표현식을 넣습니다.
- 호출마다 다른 데이터를 만들 수 있지만, 요청별 분기는 하지 않습니다.
-
전체 응답 목 예상(Mock Expectation)
- 요청 조건, 응답 본문, 상태 코드, 헤더를 하나의 규칙으로 구성합니다.
- 요청 본문, 경로 파라미터, 쿼리, 헤더, 쿠키, IP 주소 등을 기준으로 분기할 수 있습니다.
이 글의 핵심은 두 번째 계층인 목 예상입니다.
필드 수준 동적 값 설정하기
조건부 응답을 만들기 전에 Faker.js 표현식으로 단일 필드 값을 생성하는 방법부터 확인해 보겠습니다.
스키마의 문자열 필드에 {{$category.method}} 형식의 표현식을 사용하면 Apidog가 목 요청마다 새 값을 생성합니다.
{
"id": "{{$number.int(min=1000,max=9999)}}",
"customer": "{{$person.fullName}}",
"email": "{{$internet.email}}",
"product": "{{$commerce.productName}}",
"shippingAddress": "{{$location.streetAddress}}, {{$location.city}}",
"orderedAt": "{{$date.between(from='2024-01-01',to='2024-12-31',format='yyyy-MM-dd')}}"
}
실무에서 자주 쓰는 패턴은 다음과 같습니다.
- 범위가 있는 숫자:
{{$number.int(min=1000,max=9999)}} - 지정 기간의 날짜:
{{$date.between(...)}} - UUID 토큰:
{{$string.uuid}} - 이름, 이메일, 주소:
{{$person.fullName}},{{$internet.email}},{{$location.streetAddress}}
정적 문자열과 Faker.js 표현식도 함께 사용할 수 있습니다. 예를 들어 mock-jwt-{{$string.uuid}}처럼 접두사를 붙일 수 있습니다. 지역화된 데이터가 필요하면 목 로케일을 설정해 이름, 주소, 전화번호 형식을 맞출 수 있습니다. 전체 표현식은 Apidog Faker.js 참조에서 확인하세요.
여기까지는 스마트 목입니다. 값은 동적이지만 요청 조건에 따라 응답을 바꾸지는 않습니다. 분기가 필요하면 목 예상으로 이동합니다.
튜토리얼: /login에서 200 또는 401 반환하기
다음 API를 목킹한다고 가정합니다.
POST /login
Content-Type: application/json
{
"username": "alice@example.com",
"password": "whatever"
}
요구사항은 다음과 같습니다.
-
alice@example.com이면 토큰과 함께200 - 그 외 사용자면 오류 본문과 함께
401
1. Mock 또는 Advanced mock 탭 열기
작업 모드에 따라 위치가 다릅니다.
- DEBUG(요청 우선) 모드: 엔드포인트에서 Mock 탭을 엽니다.
- DESIGN(설계 우선) 모드: 엔드포인트에서 고급 목(Advanced mock) 탭을 엽니다.
두 화면 모두 동일한 예상 목록으로 연결됩니다. 아직 프로젝트가 없다면 Apidog를 다운로드한 뒤 /login 엔드포인트를 생성하거나 가져오세요.
2. 성공 예상 추가하기
새 예상(New expectation) 을 클릭하고 다음 규칙을 만듭니다.
| 항목 | 값 |
|---|---|
| 예상 이름 | login-success |
| 조건 대상 | 본문 파라미터 |
| 이름 | username |
| 조건 |
alice@example.com과 같음 |
본문 파라미터 조건은 JSON 본문에서 JSON 경로로 일치합니다. 중첩 객체라면 user.email처럼 점 표기법을 사용합니다.
응답 데이터(Response data) 에 다음 본문을 입력합니다.
{
"token": "mock-jwt-{{$string.uuid}}",
"user": {
"id": 4821,
"username": "alice@example.com",
"role": "member"
}
}
기본 HTTP 상태 코드는 200이므로 성공 응답에는 별도 설정이 필요하지 않습니다.
3. 실패 예상 추가하기
다시 새 예상(New expectation) 을 클릭하고 다음처럼 설정합니다.
| 항목 | 값 |
|---|---|
| 예상 이름 | login-failure |
| 조건 | 비워 둠 |
| HTTP 상태 코드 | 401 |
조건을 비워 두면 이 규칙은 모든 요청에 일치하는 캐치올(catch-all)이 됩니다.
응답 데이터(Response data) 는 다음과 같이 설정합니다.
{
"error": "invalid_credentials",
"message": "Username or password is incorrect."
}
이후 더 보기(More) 탭에서 HTTP 상태 코드(HTTP Status Code) 를 401로 변경하세요.
같은 탭에서 다음도 설정할 수 있습니다.
- 응답 지연(Response Delay): 밀리초 단위
- 사용자 정의 응답 헤더
- 상태 코드
예를 들어 400ms 지연을 추가하면 로그인 로딩 상태나 스피너 UI를 검증할 수 있습니다.
4. 예상 순서 확인하기
목 예상은 위에서 아래로 평가되며, 첫 번째로 일치한 규칙이 응답을 결정합니다.
따라서 순서는 반드시 다음과 같아야 합니다.
login-successlogin-failure
login-failure를 위에 놓으면 조건 없는 규칙이 모든 요청을 먼저 처리하므로 login-success는 절대 실행되지 않습니다.
목 URL을 복사한 뒤 두 요청을 테스트하세요.
# 알려진 사용자: 200과 토큰 반환
curl -X POST https://<your-mock-host>/login \
-H "Content-Type: application/json" \
-d '{"username":"alice@example.com","password":"whatever"}'
# 그 외 사용자: 401 반환
curl -X POST https://<your-mock-host>/login \
-H "Content-Type: application/json" \
-d '{"username":"stranger@example.com","password":"whatever"}'
튜토리얼: /orders/{id}에서 상태별 본문 반환하기
경로 파라미터별로 응답을 분기하면 백엔드 없이도 다양한 UI 상태를 검증할 수 있습니다.
예를 들어 다음 요구사항을 구성해 보겠습니다.
-
/orders/5001: 배송 완료 주문 -
/orders/5002: 취소된 주문 - 나머지 ID: 일반 보류 주문
배송 완료 주문 규칙
예상 이름을 order-shipped로 만들고 다음 조건을 추가합니다.
| 항목 | 값 |
|---|---|
| 조건 대상 | 경로 파라미터 |
| 이름 | id |
| 조건 |
5001과 같음 |
응답 본문은 다음과 같습니다.
{
"id": 5001,
"status": "shipped",
"total": 129.90,
"trackingNumber": "1Z{{$string.alphanumeric(length=16)}}",
"shippedAt": "{{$date.recent(days=3,format='yyyy-MM-dd')}}"
}
취소 주문 규칙
예상 이름을 order-cancelled로 만들고 id가 5002와 같은 조건을 추가합니다.
{
"id": 5002,
"status": "cancelled",
"total": 0,
"cancelledAt": "{{$date.recent(days=1,format='yyyy-MM-dd')}}",
"refundIssued": true
}
마지막으로 조건 없는 예상 하나를 추가해 일반적인 보류 주문을 반환하면 됩니다.
이때 순서는 다음처럼 구성하세요.
order-shippedorder-cancelled- 조건 없는 보류 주문 캐치올
여러 조건을 하나의 예상에 추가할 수도 있습니다. 예를 들어 경로 파라미터 id=5001과 특정 헤더를 동시에 요구하면, 두 조건이 모두 충족되어야 합니다. Apidog는 여러 조건을 AND 논리로 결합합니다.
조건은 다음 요청 요소에 적용할 수 있습니다.
- 본문
- 경로 파라미터
- 쿼리 파라미터
- 헤더
- 쿠키
- IP 주소
요청 시 오류 상태 강제하기
오류 처리를 테스트하려고 실제 백엔드를 중단할 필요는 없습니다. 클라이언트가 제어 가능한 헤더를 조건으로 사용하면 원하는 오류를 재현할 수 있습니다.
예를 들어 500 Internal Server Error를 만들려면 다음 규칙을 추가합니다.
| 항목 | 값 |
|---|---|
| 예상 이름 | server-error |
| 조건 대상 | 헤더 |
| 헤더 이름 | X-Mock-Scenario |
| 조건 |
server-error와 같음 |
| HTTP 상태 코드 | 500 |
응답 데이터는 다음과 같이 설정합니다.
{
"error": "internal_error",
"requestId": "{{$string.uuid}}",
"message": "저희 서버에 문제가 발생했습니다. 다시 시도해주세요."
}
클라이언트에서는 다음처럼 요청합니다.
curl https://<your-mock-host>/orders/5001 \
-H "X-Mock-Scenario: server-error"
같은 패턴으로 다음 상태도 테스트할 수 있습니다.
404 Not Found-
429 Too Many Requests-
더 보기(More) 탭에서
Retry-After헤더도 설정
-
더 보기(More) 탭에서
503 Service Unavailable
자동화 테스트에서 이 응답을 검증하려면 API 어설션 가이드를 함께 활용하세요.
공유 프로젝트에서는 각 예상을 로컬 목과 클라우드 목 환경에서 독립적으로 켜거나 끌 수 있습니다. 예를 들어 로컬에서는 500 규칙을 활성화하고, 팀이 사용하는 클라우드 목에서는 비활성화할 수 있습니다.
규칙으로 부족할 때: 목 스크립트
목 예상은 선언형 규칙입니다. 조건에 맞는 미리 준비된 응답을 반환하는 데 적합하지만, 합계 계산이나 요청 데이터 기반 응답 변환에는 한계가 있습니다.
다음처럼 계산이 필요하면 목 스크립트(Mock Script) 를 사용하세요.
- 요청 항목에서 주문 합계 계산
- 요청 헤더에 따라 통화 변경
- 여러 입력값으로 응답 구조 변경
- 날짜 또는 배열 연산 수행
목 스크립트는 Mock 탭 하단의 목 스크립트 섹션(Mock Script section) 에서 활성화합니다.
사용할 수 있는 전역 객체는 두 개입니다.
-
$$.mockRequestgetParam(key)headerscookiesbodyformdataurlencoded
-
$$.mockResponsesetBody()setCode()setDelay()json()headerscode
다음 스크립트는 요청 본문의 항목으로 주문 금액을 계산하고 x-currency 헤더를 응답에 반영합니다.
const body = $$.mockRequest.body;
const items = body.items || [];
const subtotal = items.reduce((sum, item) => {
return sum + item.price * item.quantity;
}, 0);
const currency = $$.mockRequest.headers["x-currency"] || "USD";
$$.mockResponse.setCode(201);
$$.mockResponse.setBody({
orderId: Math.floor(Math.random() * 90000) + 10000,
currency: currency,
subtotal: subtotal,
tax: Number((subtotal * 0.08).toFixed(2)),
total: Number((subtotal * 1.08).toFixed(2))
});
실행 흐름은 다음과 같습니다.
- 스마트 목이 초기 응답을 생성합니다.
- 목 스크립트가
$$.mockRequest와 현재$$.mockResponse를 읽습니다. - 스크립트가 계산 또는 변환을 수행합니다.
-
setBody(),setCode(),setDelay()또는 헤더 설정으로 최종 응답을 덮어씁니다. - 목 엔진이 최종 결과를 반환합니다.
JavaScript 배열 메서드나 날짜 계산이 더 필요하다면 MDN JavaScript 참조를 참고하세요.
중요한 제약: 목 스크립트와 목 예상은 함께 실행되지 않습니다
목 스크립트는 스마트 목에서만 실행됩니다.
즉, 다음 조합은 불가능합니다.
- 목 예상에 일치한 응답 + 목 스크립트 후처리
- 응답 예시 + 목 스크립트 후처리
예상이 요청과 일치하면 스크립트는 실행되지 않습니다.
따라서 엔드포인트별로 접근 방식을 선택하세요.
| 요구사항 | 적합한 기능 |
|---|---|
| 헤더, 본문, 경로 값에 따른 분기 | 목 예상 |
| 고정된 상태 코드와 미리 정의한 오류 응답 | 목 예상 |
| 합계, 세금, 날짜 등 계산된 값 | 목 스크립트 |
| 스마트 목 결과를 요청 데이터로 변형 | 목 스크립트 |
응답 우선순위 이해하기
Apidog는 목 요청을 다음 순서로 처리합니다.
-
목 예상 평가
- 목록을 위에서 아래로 검사합니다.
- 모든 조건에 일치한 첫 번째 예상이 응답을 결정합니다.
- 일치한 예상이 있으면 스마트 목은 실행되지 않습니다.
-
목 메서드 우선순위 적용
- 일치하는 예상이 없으면 프로젝트 설정 → 기능 설정 → 목 설정(Project Settings → Feature Settings → Mock Settings) 의 목 메서드 우선순위(Mock method priority) 로 이동합니다.
- 이 단계에서 스마트 목과 연결된 목 스크립트가 응답을 생성합니다.
실무에서는 다음 순서를 권장합니다.
- 가장 구체적인 조건
- 덜 구체적인 조건
- 조건 없는 캐치올 규칙
- 스마트 목 폴백
더 많은 시나리오는 API 목킹 사용 사례에서 확인할 수 있습니다.
배포 전에 확인할 제약 사항
구성 전에 다음 제한을 확인하세요.
-
매개변수 조건에서는
{{변수}}를 사용할 수 없습니다.- Apidog 프로젝트 변수와 환경 변수는 목 예상 내부에서 사용할 수 없습니다.
- 조건에는 리터럴 값을 사용하세요.
-
본문 파라미터 조건은 JSON 전용입니다.
- XML 본문에는 적용되지 않습니다.
- JSON 경로를 사용해 필드를 지정해야 합니다.
-
요청 형식은 API 사양과 일치해야 합니다.
-
form-data엔드포인트는 JSON 조건이 아니라 form-data 방식으로 구성해야 합니다.
-
-
목 스크립트에서는 로깅 함수와
pm객체를 사용할 수 없습니다.- 테스트 스크립트와 목 스크립트는 실행 환경이 다릅니다.
- 스크립트는 외부 변수에 의존하지 않도록 자체 포함형으로 작성하세요.
이 기능들은 문서상 별도의 플랜 제한이 없습니다. 로컬 목과 클라우드 목의 차이는 기능 제한이 아니라, 예상별 활성화 상태를 환경마다 독립적으로 설정할 수 있다는 점입니다.
Apidog CLI로 워크플로 자동화하기
Apidog 목킹은 GUI와 클라우드 목 URL을 중심으로 동작합니다. 실행 중인 목 서버를 시작하는 CLI 명령은 없지만, Apidog CLI는 목의 기반이 되는 API 계약을 자동화하는 데 사용할 수 있습니다.
목 응답은 엔드포인트 스키마에서 생성되므로, 목 정확도는 API 사양 정확도에 달려 있습니다. CLI와 이를 사용하는 AI 코딩 에이전트(Cursor, Claude Code, Trae, Codex)는 프로젝트의 엔드포인트와 스키마를 생성하거나 업데이트할 수 있습니다.
계약을 코드와 동기화하면 앱을 다시 열지 않아도 목 응답이 최신 스키마를 따릅니다.
프런트엔드 개발에서 목으로 계약을 검증했다면, 같은 프로젝트의 테스트 시나리오를 CI에서 실행해 실제 백엔드가 그 계약을 지키는지 확인할 수 있습니다.
apidog run -t <scenario_id> -e <env_id> -r cli
이 명령은 테스트 시나리오를 실행하고 결과를 보고합니다. 목과 백엔드 검증이 하나의 계약을 공유하게 됩니다.
설정 방법은 Apidog CLI 설치 가이드, CI 연결 방법은 GitHub Actions의 Apidog CLI 튜토리얼을 참고하세요.
자주 묻는 질문
조건이 올바른데 예상이 무시됩니다. 왜 그런가요?
대부분 예상 순서 또는 요청 형식 문제입니다.
- 예상은 위에서 아래로 평가됩니다.
- 조건 없는 캐치올 규칙이 특정 규칙보다 위에 있으면 모든 요청을 먼저 처리합니다.
- JSON 본문은 JSON 경로로, 폼 엔드포인트는 form-data 조건으로 구성해야 합니다.
기본 설정은 API 목킹 개요에서 다시 확인할 수 있습니다.
같은 응답에 목 스크립트와 목 예상을 함께 사용할 수 있나요?
아니요. 목 스크립트는 스마트 목에서만 실행됩니다. 목 예상 또는 응답 예시가 일치하면 목 스크립트는 실행되지 않습니다.
- 규칙 기반 분기: 목 예상
- 계산된 응답: 목 스크립트
기본 200 응답을 유지하면서 401 또는 500을 테스트하려면 어떻게 하나요?
클라이언트에서 제어하는 조건을 가진 전용 예상을 추가하세요. 헤더 조건이 가장 관리하기 쉽습니다.
예를 들어 X-Mock-Scenario: server-error 헤더에만 500 응답을 연결하면 기본 요청은 계속 200을 반환합니다.
조건에서 환경 변수를 사용할 수 있나요?
아니요. 목 예상의 매개변수 조건에서는 Apidog {{변수}} 값을 사용할 수 없습니다. 조건에는 리터럴 값을 입력해야 합니다.
어떤 예상도 일치하지 않으면 어떻게 되나요?
Apidog는 프로젝트 설정 → 기능 설정 → 목 설정의 목 메서드 우선순위로 돌아가 스마트 목 응답을 생성합니다.
특정 폴백 응답이 항상 필요하다면 조건 없는 캐치올 예상을 목록 맨 아래에 추가하세요.
마무리
스마트 목은 일반적인 응답을 빠르게 생성하는 데 적합합니다. 반면 목 예상은 다음처럼 요청에 따라 응답을 분기해야 할 때 사용합니다.
- 알려진 사용자면
200, 그 외에는401 - 주문 ID에 따라 배송됨 또는 취소됨 응답
- 특정 헤더가 있을 때만
500 - 상태 코드, 지연 시간, 응답 헤더를 포함한 오류 시나리오
계산된 응답이 필요할 때만 목 스크립트를 사용하세요. 단, 목 스크립트는 스마트 목에서만 실행되며 목 예상과 결합할 수 없습니다.
가장 구체적인 예상부터 위에 배치하고, 조건 없는 캐치올은 맨 아래에 두면 실제 API처럼 분기하는 목을 안정적으로 구성할 수 있습니다. Apidog를 다운로드하여 첫 조건부 목을 만들어 보세요. 신용 카드는 필요하지 않습니다.




Top comments (0)