Mock object — test qilinayotgan kodning hamkor obyektini almashtirib, undan kutilgan chaqiruvlar va o‘zaro ta’sirlarni oldindan belgilash hamda keyin tekshirish uchun yaratilgan test double. Mock odatda “qaysi metod, qanday argument bilan, necha marta va qaysi tartibda chaqirildi” degan xulqni tekshiradi. U faqat soxta qiymat qaytaruvchi stub bilan aynan bir tushuncha emas.
Expectation modeli
Test mockga kutiladigan interactionni o‘rnatadi, so‘ng system under test bajariladi va expectation tasdiqlanadi. Masalan, buyurtma tasdiqlanganda payment.charge(order_id, amount) bir marta chaqirilishi kutiladi. Metod chaqirilmasa, ortiqcha chaqirilsa yoki argument mos kelmasa test yiqiladi.
Ba’zi frameworklar record-replay usulida avval expectation yozib, keyin replay rejimiga o‘tadi. Boshqalari oddiy obyekt yaratib, yakunda assert_called_once_with kabi assertion ishlatadi. Har ikkala holatda mockning asosiy vazifasi interactionni kuzatish va tekshirishdir.
State va interaction testi
State-based test amal tugagach obyekt yoki baza holatini tekshiradi. Interaction-based test hamkor bilan aloqa qanday bo‘lganini tekshiradi. Tashqi gatewayga haqiqiy so‘rov yuborilmasligi kerak bo‘lsa, mock chaqiruvni ushlab, protokolga amal qilinganini ko‘rsatadi.
Ichki private metodlar yoki har bir mayda chaqiruvni mock qilish testni implementatsiyaga qattiq bog‘laydi. Kod natijani o‘zgartirmasdan refactor qilinsa ham test yiqiladi. Interaction assertion faqat muhim protokol — to‘lov bir marta yuborilishi, tranzaksiya commit qilinishi yoki event publish bo‘lishi — uchun ishlatiladi.
Qaytarish va xato ssenariysi
Mock chaqiruvga qiymat qaytarishi, exception chiqarishi yoki ketma-ket turli natija berishi mumkin. Bu timeout, rad etilgan to‘lov va retry kabi branchlarni deterministik tekshiradi. Async metod mocki await qilinadigan natija berishi va await sonini kuzatishi kerak.
Argument matcher aniq qiymat, tur, predikat yoki wildcard bilan moslashtiradi. Haddan tashqari keng matcher noto‘g‘ri argumentni yashiradi; haddan tashqari aniq matcher testni keraksiz tafsilotga bog‘laydi.
Interfacega moslik
Dinamik tilda mavjud bo‘lmagan metod nomini mockga yozib qo‘yish testni yolg‘on muvaffaqiyatli qilishi mumkin. Autospec yoki interface-based mock haqiqiy class/signaturedan ruxsat etilgan metodlarni oladi. Production API o‘zgarsa test erta xato beradi.
Mock tashqi xizmatning real protokolini to‘liq isbotlamaydi. Mahalliy expectation noto‘g‘ri tuzilgan bo‘lsa, test o‘tadi, integratsiya esa buziladi. Contract testing yoki integration testing real chegaradagi format va semantikani tekshiradi.
Hayot sikli
Har test yangi mock oladi yoki uning historysi tozalanadi. Umumiy global mock chaqiruvlari testlar orasida sizib, tartibga bog‘liqlik yaratadi. Verification testning assertion bosqichida bajariladi; teardown xatosi asl exceptionni yashirmasligi kerak.
Mock thread yoki async tasklar orasida ishlatilsa, call historyning xavfsizligi frameworkga bog‘liq. Parallel testda shared mockdan ko‘ra har scenario uchun mustaqil instance aniqroq.
Strict va lenient mock
Strict mock faqat oldindan ko‘rsatilgan chaqiruvlarni qabul qiladi; har qanday ortiqcha interaction testni yiqitadi. Lenient mock esa standart qiymat qaytarib, test faqat tanlangan chaqiruvlarni tekshiradi. Strict rejim kichik, barqaror protokolda foydali, ammo logging yoki observability qo‘shilganda ko‘p asossiz xato beradi.
Chained calllar
client.users().by_id().save() kabi uzun call chainni mocklash production obyekt tuzilishini testga ko‘chiradi. Bu Law of Demeter buzilishining belgisi bo‘lishi mumkin. Test qilinayotgan komponentga kerakli bitta yuqori darajali port berish expectationni soddalashtiradi. Deep stub qulay ko‘rinsa ham, oraliq qaytish turlari o‘zgarganda ko‘plab testlar sinadi.