스마트 목(Smart mock)은 몇 초 만에 가짜 API를 제공합니다. 엔드포인트 스키마를 읽어 그럴듯한 데이터를 반환합니다. 예를 들어, 실제와 같은 이메일 주소, 합리적인 타임스탬프, xJ8kQ가 아닌 이름 등이 있습니다. 대부분의 프런트엔드 작업에서는 이 정도면 충분히 막힌 부분을 해결할 수 있습니다.
하지만 스마트 목(Smart mock)이 해결할 수 없는 경우도 있습니다. 예를 들어, /login이 알려진 사용자에게는 200을 반환하고 그렇지 않은 사용자에게는 401을 반환하도록 하고 싶을 수 있습니다. 또는 /orders/{id}가 특정 ID에는 배송된 주문을, 다른 ID에는 취소된 주문을 반환하도록 하고 싶을 수 있습니다. 또 프로덕션에 배포하기 전에 오류 처리가 제대로 작동하는지 확인하기 위해 필요할 때 500 오류를 강제로 발생시키고 싶을 수도 있습니다. 스마트 목은 엔드포인트당 하나의 형태만 반환하므로 요청에 따라 분기할 수 없습니다. 이 가이드는 바로 이 간극을 메웁니다.
Apidog는 두 가지 기능으로 이를 해결합니다. 규칙 기반 조건부 응답을 위한 목 예상(mock expectations)과 규칙으로는 표현할 수 없는 로직을 위한 목 스크립트(mock scripts)입니다. 이 튜토리얼은 구체적인 예시를 통해 두 가지 모두를 보여주며, 사용자 정의 규칙이 스마트 목보다 항상 우선하도록 우선순위 순서를 설명합니다. 기본 사항에 익숙하지 않다면 API 목킹 개요가 좋은 워밍업이 될 것이며, 이 가이드에서는 Apidog를 사용할 것입니다. OpenAPI Initiative는 이 모든 것을 가능하게 하는 계약 우선 워크플로를 문서화하고 있습니다.
조건부 목킹(Conditional Mocking)이 실제로 의미하는 것
조건부 목은 규칙입니다. 즉, 들어오는 요청이 이렇게 보이면 저것을 반환하는 것입니다. Apidog는 두 가지 계층으로 이러한 규칙을 구축합니다.
첫 번째 계층은 엔드포인트 스키마 내의 필드 수준 사용자 정의입니다. 필드를 고정된 값에 고정하거나 동적인 Faker.js 표현식을 연결하여 호출마다 값이 변경되도록 할 수 있습니다. 이는 필드가 포함하는 내용을 제어하지만, 엔드포인트에 대해 여전히 하나의 응답 형태를 반환합니다.
두 번째 계층은 전체 응답 목 예상(full-response mock expectation)입니다. 예상은 선택적 조건과 자체 응답 본문, 상태 코드, 헤더를 가진 명명된 규칙입니다. 조건이 없는 예상은 고정된 데이터를 무조건 반환합니다. 조건이 있는 예상은 요청이 일치할 때만 데이터를 반환합니다. 이러한 예상을 몇 개 쌓으면 실제 분기가 가능해집니다. 즉, 요청이 조건 A와 일치하면 응답 B를, 헤더가 누락되면 오류 본문을, 경로 매개변수마다 다른 페이로드를 얻을 수 있습니다.
두 번째 계층 덕분에 온디맨드 오류 상태와 요청별 본문이 가능해집니다. 이 가이드의 나머지 부분은 이 두 번째 계층에 대해 다룹니다.
필드 수준 동적 값 먼저
분기하기 전에 단일 필드가 값을 얻는 방법을 이해하는 것이 도움이 됩니다. 조건부 응답에서 동일한 구문을 재사용할 것이기 때문입니다.
엔드포인트 스키마 내에서 모든 문자열 필드는 {{$category.method}} 형식으로 작성된 Faker.js 표현식을 포함할 수 있습니다. Apidog는 JSON 스키마 정의에 이미 선언된 필드 유형을 사용하여 목 호출마다 이를 새롭게 해석합니다.
{
"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(...)}}는 범위와 형식을 고정합니다. 단일 필드에 정적 텍스트와 여러 표현식을 연결할 수 있으며, 위 주소가 이렇게 구성됩니다. 지역별 데이터가 필요한 경우 Apidog는 사용자 정의 가능한 목 로케일을 지원하여 이름, 주소, 전화번호가 지정된 언어 또는 국가와 일치하도록 합니다. Apidog의 Faker.js 참조는 전체 메서드 카탈로그를 다룹니다.

이것이 스마트 목 영역입니다. 동적이지만 조건부는 아닙니다. 요청에 따라 분기하려면 예상(expectations)으로 이동해야 합니다.
튜토리얼: 200 또는 401을 반환하는 로그인 엔드포인트
전형적인 사례: POST /login은 username과 password가 포함된 JSON 본문을 받습니다. 알려진 사용자는 토큰과 함께 200을 받아야 합니다. 다른 모든 사용자는 401을 받아야 합니다.
올바른 탭 열기
이를 구성하는 위치는 작업 모드에 따라 다릅니다.
- DEBUG (요청 우선) 모드에서는 엔드포인트를 열고 Mock 탭을 클릭합니다.

- DESIGN (설계 우선) 모드에서는 엔드포인트를 열고 고급 목(Advanced mock) 탭을 클릭합니다.

두 가지 모두 동일한 예상 목록으로 이어집니다. 따라 하고 싶지만 아직 앱이 없다면 Apidog를 다운로드하고 먼저 /login 엔드포인트를 가져오거나 생성하세요.
성공 예상 추가
새 예상(New expectation)을 클릭합니다. login-success와 같은 예상 이름(expectation name)을 지정합니다. 이제 조건을 추가합니다. username이 JSON 요청 본문에 있으므로 본문 매개변수로 일치시킵니다. 대상 속성의 JSON 경로, 즉 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 상태 코드(HTTP Status Code)는 200이므로 성공 경로에는 다른 것을 건드릴 필요가 없습니다.
실패 예상 추가
새 예상(New expectation)을 다시 클릭합니다. 이름을 login-failure로 지정하고 조건은 비워두어 모든 것을 처리하는 캐치올(catch-all) 역할을 하도록 합니다. 응답 데이터(Response data)를 오류 본문으로 설정합니다.
{
"error": "invalid_credentials",
"message": "Username or password is incorrect."
}
이것은 기본 상태가 아닌 상태가 필요합니다. 예상의 더 보기(More) 탭을 열고 HTTP 상태 코드(HTTP Status Code)를 401로 설정합니다. 그곳에서 더 보기 탭이 밀리초 단위의 응답 지연(Response Delay)(기본값 0)과 사용자 정의 응답 헤더를 설정하는 곳이기도 함을 참고하세요. 400ms 지연은 로딩 스피너가 실제로 렌더링되는지 확인하는 저렴한 방법입니다.
순서가 중요합니다
예상(Expectations)은 위에서 아래로 평가되며, 첫 번째 일치하는 것이 우선합니다. 따라서 login-success는 login-failure 위에 있어야 합니다. username이 alice@example.com과 같은 요청은 첫 번째 규칙과 일치하고 토큰을 반환합니다. 다른 모든 것은 조건 없는 실패 규칙으로 넘어가 401을 받게 됩니다. 순서를 바꾸면 빈 조건 규칙이 모든 것과 일치하여 성공 사례가 전혀 발생하지 않을 것입니다.
엔드포인트에서 목 URL(mock 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/{id}가 특정 ID에는 배송된 주문을 반환하고 다른 ID에는 취소된 주문을 반환하도록 하고 싶을 수 있습니다.
상태별로 하나의 예상(expectation)을 생성합니다. 각 예상에 대해 경로 매개변수 id에 대한 조건을 추가한 다음 일치하는 응답 데이터(Response data)를 채웁니다.
예상 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
}
마지막으로 조건이 없는 예상을 추가하여 일반적인 보류 중인 주문을 반환하도록 합니다. 이렇게 하면 다른 모든 ID가 유효한 응답을 받게 됩니다. 캐치올(catch-all) 위에 특정 규칙을 배치하고 저장하면 요청 시 모든 주문 상태를 렌더링하는 목(mock)을 갖게 됩니다. 조건을 혼합하는 것도 작동합니다. 경로 조건과 함께 헤더 조건을 추가하면 둘 다 충족되어야 합니다. Apidog는 여러 조건을 AND 논리(문서 용어로 조건의 교집합)로 결합하기 때문입니다.
조건은 본문과 경로에만 국한되지 않습니다. 쿼리 매개변수, 헤더 매개변수, 쿠키 매개변수, 심지어 IP 주소까지 일치시킬 수 있어 테스트 중에 특정 클라이언트에 대한 응답을 제한할 수 있습니다.
요청 시 오류 상태 강제 적용
오류 응답을 테스트하기 위해 백엔드가 고장 날 필요는 없습니다. 예상(expectation)과 더 보기(More) 탭을 사용하면 원하는 모든 상태를 얻을 수 있습니다.
500 오류를 강제 적용하려면, 클라이언트에서 제어할 수 있는 조건(예: 헤더 X-Mock-Scenario가 server-error와 같음)을 가진 예상을 추가합니다. 응답 데이터(Response data)를 실제 오류 본문으로 설정하고, 더 보기 탭에서 HTTP 상태 코드(HTTP Status Code)를 500으로 설정합니다.
{
"error": "internal_error",
"requestId": "{{$string.uuid}}",
"message": "저희 서버에 문제가 발생했습니다. 다시 시도해주세요."
}
이제 동일한 엔드포인트가 기본적으로 정상적인 200을 제공하고, 해당 헤더를 보낼 때마다 500을 제공합니다. 404, 429 (더 보기 탭에서 Retry-After 헤더 설정), 또는 503에 대해서도 동일하게 수행하세요. 이제 프런트엔드 오류 처리가 마침내 처리할 것이 생겼습니다. 자동화된 검사에서 이러한 응답을 어설션하는 경우, API 어설션 가이드가 이 설정과 잘 어울립니다.
공유 프로젝트를 위한 한 가지 세부 사항: 각 예상은 예상 목록에서 로컬 및 클라우드 목 환경에 대해 독립적으로 켜거나 끌 수 있습니다. 따라서 로컬에서 500 규칙을 활성화된 상태로 유지하면서, 팀원들이 사용하는 클라우드 목에서는 비활성화할 수 있습니다.
규칙으로 부족할 때: 목 스크립트
예상(Expectations)은 선언적입니다. 일치하고 반환하지만 계산할 수는 없습니다. 요청에서 파생된 필드, 항목에서 합산된 총계, 또는 여러 입력에 따라 모양이 바뀌는 본문이 필요한 경우 목 스크립트를 사용합니다.
목 스크립트는 목 응답에 대해 실행되는 JavaScript입니다. 목(Mock) 탭 하단의 목 스크립트 섹션(Mock Script section)에 있으며 토글 스위치로 활성화됩니다. 스크립트는 두 가지 전역 객체를 노출합니다.
$$.mockRequest:getParam(key)를 통해 들어오는 요청을 읽고,headers,cookies,body,formdata,urlencoded를 포함합니다.$$.mockResponse:setBody(),setCode(),setDelay(),json(), 그리고headers와code속성을 통해 나가는 응답의 형태를 만듭니다.
다음은 게시된 항목에서 주문 총액을 계산하고 호출자의 통화 헤더를 다시 반환하는 스크립트입니다.
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를 읽고, 로직을 적용하고, $$.mockResponse.setBody()(필요에 따라 setCode, setDelay, 또는 headers도)를 호출하며, 엔진은 최종 결과를 반환합니다. 배열 메서드나 날짜 계산으로 로직을 더 확장하고 싶다면 MDN JavaScript 참조가 훌륭한 동반자가 될 것입니다.
사람들이 혼동하는 한 가지 규칙
목 스크립트는 스마트 목에서만 작동합니다. 목 예상(mock expectations)이나 응답 예시에는 적용되지 않습니다. 이것이 가장 중요한 점입니다. 목 스크립트를 예상 기반 응답과 결합할 수 없습니다. 예상이 요청과 일치하면 스크립트는 절대 실행되지 않습니다. 따라서 엔드포인트당 하나의 방식을 선택하세요. 고정된 조건에 따라 분기하고 미리 준비된 본문을 반환할 때는 예상을 사용하세요. 스마트 목이 생성한 기본 출력에서 계산된 출력이 필요할 때는 목 스크립트를 사용하세요.
우선순위가 어떻게 결정되는가
모든 것을 종합하면, Apidog가 모든 목 요청에 대해 따르는 순서는 다음과 같습니다.
- 예상을 위에서 아래로 확인합니다. 조건이 모두 일치하는 첫 번째 예상이 승리하며, 해당 응답이 반환됩니다. 이것이 사용자 정의 규칙이 스마트 목을 이기는 이유입니다. 일치하는 예상은 그 아래의 모든 것을 단락시킵니다.
- 일치하는 예상이 없으면 Apidog는 프로젝트 설정 - 기능 설정 - 목 설정(Project Settings - Feature Settings - Mock Settings)에서 설정한 목 메서드 우선순위(Mock method priority)로 돌아갑니다. 이 계층에서 스마트 목(및 이에 연결된 모든 목 스크립트)이 응답을 생성합니다.
개념 모델은 간단합니다. 구체적인 규칙이 먼저, 생성된 데이터가 그 다음입니다. 가장 구체적인 것부터 가장 덜 구체적인 순서로 예상을 정렬하고, 확실한 일치를 원한다면 맨 아래에 빈 조건의 캐치올(catch-all)을 유지하고, 나머지는 스마트 목이 처리하도록 하세요. 각 계층에 언제 의존해야 하는지에 대한 더 깊은 내용은 API 목킹 사용 사례 가이드에서 일반적인 시나리오를 기능에 매핑합니다.
배포 전에 알아야 할 주의사항
몇 가지 제약 사항은 혼란스러운 디버깅 세션을 줄여줄 것입니다.
- 매개변수 조건은
{{변수}}를 지원하지 않습니다. Apidog 프로젝트 및 환경 변수는 목 예상(mock expectations) 내에서 사용할 수 없으므로 조건에 리터럴 값을 넣으세요. - 본문 매개변수 조건은 JSON 전용이며, XML이 아니며, 이름 필드의 JSON 경로를 통해 일치해야 합니다.
- 조건의 요청 본문 형식은 API 사양과 일치해야 합니다. form-data 엔드포인트는 JSON이 아닌 form-data 배치로 목킹되어야 합니다.
- 목 스크립트 내부에는 로깅 함수가 없으며,
pm객체는 사용할 수 없습니다(테스트 스크립트와 다른 실행 환경입니다). 또한 Apidog 변수를 사용할 수 없습니다. 스크립트 로직은 자체 포함되도록 유지하세요.
이러한 기능 중 어느 것도 문서에 계획 제한(plan gating)을 두지 않습니다. 유일한 로컬 대 클라우드 구분은 기능적입니다. 즉, 이전에 설명한 환경별 독립적인 켜기/끄기 토글이지, 유료 기능이 아닙니다.
Apidog CLI로 워크플로 자동화
Apidog에서의 목킹(Mocking)은 GUI 및 클라우드 기능입니다. 목 엔진은 로컬 및 클라우드 목 URL에서 엔드포인트를 제공하며, 실행 중인 목 서버를 시작하는 CLI 명령은 없습니다. Apidog CLI가 추가하는 것은 이러한 목이 구축되는 리소스에 대한 제어입니다.
목 응답은 엔드포인트 스키마에서 생성되므로, 목의 정확성은 사양의 정확성을 따릅니다. CLI 및 이를 구동하는 AI 코딩 에이전트(Cursor, Claude Code, Trae, Codex)는 프로젝트에서 엔드포인트와 스키마를 생성하고 업데이트할 수 있습니다. 코드에서 계약을 변경하고 동기화하면, 아무도 앱을 다시 열 필요 없이 목 출력이 올바르게 유지됩니다.
목이 프런트엔드 작업을 해결하면, 동일한 프로젝트의 테스트 시나리오는 CI에서 헤드리스로 실행되어 목이 설명한 계약에 대해 실제 백엔드를 검증합니다.
apidog run -t <scenario_id> -e <env_id> -r cli
이 단일 명령은 테스트 시나리오를 실행하고 결과를 보고하므로, 목과 검증이 하나의 진실의 원천을 공유합니다. Apidog CLI 설치 가이드는 설정 방법을 다루고, GitHub Actions의 Apidog CLI 튜토리얼은 이를 파이프라인에 연결하는 방법을 설명합니다.
자주 묻는 질문
조건이 올바르게 보여도 왜 내 예상(expectation)이 무시되나요? 거의 항상 순서 문제 또는 형식 불일치 때문입니다. 예상은 위에서 아래로 평가되며 첫 번째 일치하는 것이 승리하므로, 특정 규칙 위에 있는 광범위한 빈 조건 규칙은 요청을 삼켜버릴 것입니다. 또한 본문 형식이 사양과 일치하는지 확인하세요 (JSON 본문의 경우 JSON 경로, 폼 엔드포인트의 경우 폼 데이터 배치). 다시 확인하고 싶다면 API 목킹 개요에서 기본 설정을 다룹니다.
같은 응답에 목 스크립트와 목 예상(expectation)을 모두 사용할 수 있나요? 아니요. 목 스크립트는 스마트 목에서만 실행됩니다. 목 예상과 응답 예시에는 무시됩니다. 예상이 일치하면 스크립트는 절대 실행되지 않으므로, 엔드포인트당 한 가지 접근 방식을 선택하세요. 규칙 기반 분기에는 예상을, 계산된 출력에는 스크립트를 사용하세요.
기본 200 응답을 깨지 않고 401 또는 500을 반환하려면 어떻게 해야 하나요? 클라이언트에서 제어할 수 있는 조건(헤더가 잘 작동합니다)을 가진 전용 예상을 추가한 다음, 해당 예상의 더 보기 탭을 열고 HTTP 상태 코드를 설정하세요. 기본 응답은 200으로 유지되며, 조건이 일치할 때만 오류가 발생합니다.
조건에서 환경 변수를 사용할 수 있나요? 아니요. Apidog {{변수}} 값은 목 예상 내에서 사용할 수 없으며, 매개변수 조건은 {{변수}}를 지원하지 않습니다. 조건에는 리터럴 값을 사용하세요.
어떤 예상도 일치하지 않으면 어떻게 되나요? Apidog는 프로젝트 설정 - 기능 설정 - 목 설정(Project Settings - Feature Settings - Mock Settings)의 목 메서드 우선순위로 돌아가 스마트 목이 스키마에서 응답을 생성합니다. 대신 특정 폴백을 보장하려면 빈 조건의 캐치올(catch-all) 예상을 추가하는 것이 좋습니다.
마무리
스마트 목은 일반적인 경우를 처리하며, 목 예상은 만약이 들어가는 모든 것을 처리합니다. 알려진 사용자에게는 200을, 그렇지 않은 경우 401을, 상태별로 다른 주문 본문을, 요청 시 500을 반환하는 식입니다. 규칙으로 표현할 수 없는 계산된 출력이 필요할 때만 목 스크립트를 사용하고, 목 스크립트는 스마트 목에서만 실행된다는 점을 기억하세요. 우선순위 순서(구체적인 예상이 먼저, 생성된 데이터가 그 다음)를 염두에 두면 실제 API와 똑같이 분기하는 목을 만들 수 있습니다. Apidog를 다운로드하여 첫 조건부 목을 무료로 만들어 보세요. 신용 카드가 필요하지 않습니다.
