Mocking یعنی شبیهسازی رفتار یک Dependency یا External System بهجای استفاده از نمونه واقعی آن، تا بتوانیم API یا سیستم خودمان را در شرایط کنترلشده تست کنیم.
به زبان ساده، وقتی یک سرویس برای کار کردن به سرویس دیگری وابسته است ولی آن سرویس واقعی در دسترس نیست، آماده نیست، هزینهبر است، کند است یا نمیخواهیم در تست به آن وابسته باشیم، از Mock استفاده میکنیم.
مثلاً اگر Customer Service برای استعلام کد پستی به یک External Address API وصل میشود، در تست میتوانیم بهجای سرویس واقعی، یک Mock Response برگردانیم.
Service Virtualization از Mocking گستردهتر و حرفهایتر است.
در Virtualization ما فقط یک پاسخ ساده جعلی برنمیگردانیم؛ بلکه یک سرویس شبیهسازیشده میسازیم که میتواند رفتارهای مختلف یک سیستم وابسته را تقلید کند، مثل:
Success Response
Error Response
Timeout
Slow Response / Latency
Invalid Payload
Different Status Codes
Stateful Behavior
یعنی Virtual Service میتواند مثل یک Dependency واقعی رفتار کند، نه فقط یک جواب ثابت.
در تست Web API، خیلی وقتها سرویس ما به این موارد وابسته است:
Database
Payment Gateway
SMS Service
Notification Service
Core Banking System
Identity Provider
Partner API
Fraud Detection Service
اگر این وابستگیها همیشه واقعی باشند، تست مشکل میشود چون:
سرویس واقعی ممکن است آماده نباشد
داده واقعی ممکن است نداشته باشیم
پاسخها قابل کنترل نباشند
تست flaky شود
هزینه یا ریسک بالا برود
سناریوهای خطا را نتوانیم راحت بازتولید کنیم
اینجاست که Mocking و Service Virtualization وارد میشوند.
معمولاً سادهتر است و برای شبیهسازی یک Response یا رفتار محدود استفاده میشود.
مثلاً:
GET /external/customer-score/123
بهجای سرویس واقعی، یک Mock Server همیشه این را برگرداند:
{ "score": 700 }
پیشرفتهتر است و میتواند بسته به Request یا شرایط، رفتارهای مختلف نشان دهد.
مثلاً:
اگر customerId = 123 → 200 OK
اگر customerId = 999 → 404 Not Found
اگر header خاصی وجود نداشت → 401 Unauthorized
اگر سناریوی delay فعال بود → پاسخ با 5 ثانیه تأخیر
اگر سرویس پایین فرض شده → 503 Service Unavailable
در این سرفصل خوب است اسم Test Double را هم بدانی.
Test Double یک اصطلاح کلی برای هر جایگزین تستیِ dependency واقعی است. انواع معروف آن:
Dummy
Stub
Fake
Spy
Mock
در آزمون لازم نیست تفاوت همه را خیلی عمیق بدانی، ولی بدانی Mock یکی از انواع Test Double است، خوب است.
Stub معمولاً دادهی ثابت برمیگرداند و رفتار پیچیده ندارد.
مثلاً همیشه برای استعلام مشتری:
{ "customerId": 123, "status": "ACTIVE" }
را برمیگرداند.
Mock علاوه بر برگرداندن داده، میتواند برای Verification هم استفاده شود؛ یعنی بررسی کند که آیا dependency با پارامتر درست، تعداد دفعات درست یا ترتیب درست صدا زده شده یا نه.
مثلاً:
آیا Payment Service دقیقاً یکبار صدا زده شد؟
آیا SMS Service بعد از ثبت تراکنش صدا زده شد؟
آیا Header درست ارسال شد؟
Fake یک پیادهسازی سبک ولی واقعیتر از dependency است.
مثلاً بهجای PostgreSQL از یک In-memory DB برای تست استفاده کنیم.
یک Virtual Service میتواند این موارد را تقلید کند:
HTTP Status Codes
Response Body
Headers
Latency / Delay
Timeout
Connection Failure
Malformed Response
Business Error
Stateful Scenario
Rate Limiting / 429
Authentication Failure
فرض کن API زیر را داریم:
POST /v1/transfers
این API بعد از ثبت انتقال وجه باید به Fraud Detection Service درخواست بزند.
اگر Fraud Service واقعی در دسترس نباشد، برای تست میتوانیم یک Virtual Service بسازیم که این سناریوها را برگرداند:
200 OK { "fraud": false }
200 OK { "fraud": true }
پاسخ بعد از 10 ثانیه
503 Service Unavailable
400 Bad Request
این یعنی میتوانیم بدون وابستگی به سرویس واقعی، رفتار سیستم خودمان را در همه این سناریوها تست کنیم.
Mock Server ابزاری است که درخواست API را دریافت میکند و پاسخهای از پیش تعریفشده برمیگرداند.
در تست API، Mock Server برای این کارها مفید است:
شبیهسازی سرویس وابسته
توسعه قبل از آمادهشدن سرویس واقعی
تست سناریوهای خطا
تست contract بین سرویسها
تست شرایط نادر مثل Timeout یا 500
وقتی dependency واقعی آماده نیست
وقتی dependency ناپایدار است
وقتی هزینه استفاده از dependency واقعی زیاد است
وقتی میخواهیم سناریوی خاص را دقیق کنترل کنیم
وقتی تست باید سریع و repeatable باشد
وقتی میخواهیم خطاهای خاص را بازتولید کنیم
اگر فقط یک Mock Response ثابت داشته باشیم، ممکن است خیلی از ریسکهای واقعی را نبینیم.
مثلاً اگر همیشه Fraud Service فقط 200 OK برگرداند، اینها را از دست میدهیم:
Timeout
429 Too Many Requests
Malformed JSON
500 Internal Server Error
Slow Response
Schema Change
Authentication Failure
برای همین در تست حرفهای، فقط happy path mock کافی نیست.
وقتی از Mock یا Virtual Service استفاده میکنیم، یک ریسک مهم داریم:
ممکن است Mock با سرویس واقعی همخوان نباشد.
مثلاً Mock میگوید:
{ "customerName": "Ali" }
ولی سرویس واقعی در اصل این را میدهد:
{ "fullName": "Ali" }
در این حالت تست روی Mock پاس میشود ولی در محیط واقعی سیستم Fail میکند.
برای همین باید Mock یا Virtual Service با Contract / Swagger / OpenAPI سرویس واقعی همراستا باشد.
کاهش وابستگی به سیستمهای خارجی
سریعتر شدن تست
قابلتکرار شدن تست
امکان تست سناریوهای خطا
کاهش هزینه
توسعه موازی تیمها
تست زودتر از آمادهشدن dependency واقعی
کنترل کامل روی responseها
ممکن است Mock با واقعیت متفاوت باشد
ممکن است فقط happy path را پوشش دهد
ممکن است latency، concurrency یا رفتار واقعی را دقیق شبیهسازی نکند
اگر به Mock بیش از حد اعتماد کنیم، integration bugها دیر کشف میشوند
ممکن است تست روی Mock سبز باشد ولی روی سیستم واقعی fail شود
باید فقط سناریوی موفق را Mock نکنیم. این سناریوها مهماند:
200 Success
400 Bad Request
401 / 403
404
409 Conflict
429 Too Many Requests
500 / 503
Timeout
Slow Response
Malformed Response
Unexpected Field / Missing Field
Schema Mismatch
Unit Test
Component / Service Test
API Test
Integration Test سبک
Consumer-driven Contract Test
حتی در UI Test اگر backend واقعی آماده نباشد
در دنیای API Testing، Mocking میتواند برای این استفاده شود:
ساخت Mock Server برای endpointها
تست frontend قبل از آمادهشدن backend
تست backend قبل از آمادهشدن سرویس وابسته
شبیهسازی سناریوهای خاص
ساخت data setهای قابلکنترل
Backend Tester باید بتواند:
تشخیص دهد کجا باید از Mock استفاده کند و کجا از real dependency
بداند Mocking جایگزین کامل Integration Testing نیست
سناریوهای error handling را با virtual service تست کند
بررسی کند API در برابر timeout, 500, 429, invalid payload چه رفتاری دارد
Contract mismatch بین mock و سرویس واقعی را در نظر بگیرد
تشخیص دهد failure از API خودش است یا از dependency mockشده/واقعی
در پاسخ امتحانی فقط نگویید:
Mocking یعنی شبیهسازی سرویس.
این جواب ناقص است. پاسخ خوب باید این کلیدواژهها را داشته باشد:
Dependency, External Service, Mock Server, Virtual Service, Stub, Test Double, Controlled Response, Error Simulation, Timeout, Latency, Contract Alignment, Integration Risk
Mocking یعنی جایگزین کردن یک Dependency یا External Service واقعی با یک نمونه شبیهسازیشده تا بتوان سیستم را در شرایط کنترلشده تست کرد. Service Virtualization شکل پیشرفتهتری از این مفهوم است که علاوه بر برگرداندن Response ثابت، میتواند رفتارهایی مثل Timeout، Latency، Error Response، Invalid Payload و سناریوهای stateful را شبیهسازی کند. این رویکرد برای تست APIهایی که به سرویسهای خارجی مثل Payment Gateway، Fraud Service یا Notification Service وابستهاند بسیار مهم است. با این حال، Mocking جایگزین کامل Integration Testing نیست و باید مطمئن شد که Mock با Contract سرویس واقعی همخوان است.
Mocking Service Virtualization Mock Server Virtual Service Test Double Stub Fake Spy Dependency External Service Controlled Response Error Simulation Timeout Latency Malformed Response Contract Testing Contract Alignment Integration Risk Happy Path Error Path
Mocking (شبیهسازی یک dependency یا external service بهجای نمونه واقعی): برای تست سیستم در شرایط کنترلشده و بدون وابستگی به سرویس واقعی استفاده میشود.
Service Virtualization (شبیهسازی پیشرفته یک سرویس وابسته): برای تقلید رفتارهای مختلف سرویس واقعی مثل success, error, timeout, latency و stateful behavior استفاده میشود.
Mock Server (سروری که Request تستی را دریافت و Response از پیش تعریفشده برمیگرداند): برای تست API و شبیهسازی dependencyها استفاده میشود.
Virtual Service (سرویس شبیهسازیشده با رفتار نزدیکتر به سیستم واقعی): برای تست حرفهایتر سناریوهای dependency بهکار میرود.
Test Double (نام کلی برای جایگزین تستی dependency واقعی): شامل Dummy, Stub, Mock, Fake و Spy است.
Stub (جایگزینی که معمولاً داده ثابت برمیگرداند): برای تست سادهی رفتار سیستم در برابر یک dependency استفاده میشود.
Fake (پیادهسازی سبک ولی کاربردیتر از dependency): مثل In-memory DB بهجای دیتابیس واقعی.
Spy (شیء تستی برای ثبت و مشاهده تعاملات): برای بررسی اینکه متدها با چه پارامتر و چند بار صدا زده شدهاند استفاده میشود.
Dependency (سیستم یا مؤلفهای که API به آن وابسته است): مثل Database, Payment Gateway, Notification Service یا Fraud Service.
External Service (سرویس بیرونی وابسته به API): برای مثال سرویس بانکی، سرویس احراز هویت یا سرویس پیامک.
Controlled Response (پاسخ از پیش کنترلشده): برای ساخت سناریوهای قابل پیشبینی در تست استفاده میشود.
Error Simulation (شبیهسازی خطاهای سرویس وابسته): مثل 500, 503, timeout, invalid payload و 429.
Timeout (پاسخندادن dependency در زمان مورد انتظار): یکی از سناریوهای مهم برای تست error handling و resiliency سیستم است.
Latency (تأخیر در پاسخ dependency): برای بررسی رفتار API در برابر کندی سرویسهای وابسته تست میشود.
Malformed Response (پاسخ با ساختار خراب یا ناسازگار): برای تست robustness و validation در API استفاده میشود.
Contract Testing (بررسی سازگاری بین Consumer و Provider بر اساس Contract): برای جلوگیری از mismatch بین mock و سرویس واقعی مهم است.
Contract Alignment (همراستایی mock با Swagger/OpenAPI یا قرارداد واقعی سرویس): برای معتبر ماندن نتایج تست ضروری است.
Integration Risk (ریسک اختلاف بین رفتار mock و سرویس واقعی): اگر dependency فقط با mock تست شود، ممکن است در محیط واقعی failure رخ دهد.
Happy Path (سناریوی موفق عادی): فقط یکی از سناریوهایی است که باید mock شود و بهتنهایی کافی نیست.
Error Path (سناریوهای خطا و failure): مثل timeout، 500، invalid response و unauthorized که باید با virtualization پوشش داده شوند.
مرور فشردهی Mocking و Service Virtualization در تست API با تمرکز بر شبیهسازی dependencyها، Mock Server، سناریوهای خطا مثل timeout و 500، و ریسک اختلاف بین mock و سرویس واقعی.
#APITesting
#Mocking
#ServiceVirtualization
#BackendTesting
#WebAPI