Mock — یہ کیا ہے، mock اشیاء اور ٹیسٹ کے لیے لائبریریاں

مصنف: IT Sectr اشاعت: 2026-04-10 مطالعے کا وقت: 8 منٹ

Mock ایک متبادل شے ہے جو حقیقی جزو کے رویے کی نقل کرتی ہے اور اس کے ساتھ تعاملات کی تصدیق کرنے کی اجازت دیتی ہے۔ Stub کے برعکس، جو صرف ایک پہلے سے طے شدہ قیمت لوٹاتا ہے، Mock طریقہ کار کی پکار، منتقل کردہ دلائل اور پکاروں کی تعداد کو ریکارڈ کرتا ہے۔ Mockito (2024) کے مطابق، Mock Java اور Kotlin پروجیکٹس میں Test Double کی سب سے مقبول قسم ہے، جو موبائل ایپلیکیشنز کے 70% سے زیادہ یونٹ ٹیسٹ میں استعمال ہوتی ہے۔

اہم نکات

  • Mock — ایک شے جو تعامل کی تصدیق کرتی ہے: کون سے طریقہ کار بلائے گئے، کن دلائل کے ساتھ اور کتنی بار
  • Mockito — Java اور Android پروجیکٹس میں Mock بنانے کے لیے سب سے مقبول لائبریری
  • MockK — Kotlin کے لیے Mockito کا متبادل، coroutine اور sealed class کے لیے مقامی تعاون کے ساتھ
  • Behavior verification — Mock اور Stub کے درمیان کلیدی فرق: Mock رویے کی تصدیق کرتا ہے، حالت کی نہیں
  • Over-mocking — اہم مخالف نمونہ: mock صرف بیرونی انحصار کے لیے استعمال ہونا چاہیے

Mock کیا ہے؟

Mock ایک شے ہے جو mocking فریم ورک (Mockito, MockK, EasyMock) کے ذریعے بنائی جاتی ہے، جو ایک انٹرفیس یا کلاس کی نقل کرتی ہے اور اپنے طریقہ کار کی تمام پکاروں کو ریکارڈ کرتی ہے۔ ڈیولپر توقعات متعین کرتا ہے: طریقہ کار X کو دلائل Y کے ساتھ بلایا جائے گا اور Z لوٹائے گا۔ ٹیسٹ کے عمل میں آنے کے بعد، Mock تصدیق کرتا ہے کہ توقعات حقیقی پکاروں سے مماثل ہیں۔

یہ اصطلاح Test Doubles کے تھیٹر کے استعارے سے آئی ہے: Mock ایک «نقّال» ہے جو (Dummy کی طرح) صرف اسٹیج پر کھڑا نہیں ہوتا بلکہ ایک کردار ادا کرتا ہے اور تصدیق کرتا ہے کہ اس کے ساتھ تعامل درست تھا یا نہیں۔ اگر ٹیسٹ کے تحت کوڈ نے اس طریقہ کار کو نہیں بلایا جس کی Mock توقع کر رہا تھا، یا غلط دلائل کے ساتھ بلایا — تو ٹیسٹ توقع کی خلاف ورزی کے پیغام کے ساتھ ناکام ہو جاتا ہے۔

Mock کیسے کام کرتا ہے

Mock فریم ورک فیکٹری کے ذریعے بنایا جاتا ہے: mockk<MyInterface>() یا Mockito.mock(MyClass.java)۔ فریم ورک ایک پراکسی شے تیار کرتا ہے جو تمام طریقہ کار پکاروں کو روکتا ہے۔ ہر پکار کا موازنہ پہلے سے متعین توقعات سے کیا جاتا ہے۔ اگر پکار توقع سے مماثل ہو — مخصوص قیمت لوٹائی جاتی ہے۔ اگر نہیں — Mock ترتیب کے مطابق ڈیفالٹ قیمت لوٹاتا ہے یا استثنا پھینکتا ہے۔

Mock کب ضروری ہے

Mock ضروری ہے جب ٹیسٹ کے تحت کوڈ ایسے اجزاء کے ساتھ تعامل کرتا ہے جن کے ضمنی اثرات ہوں: سرور پر ڈیٹا بھیجنا، ڈیٹابیس میں لکھنا، لاگنگ، analytics، نیویگیشن، سسٹم ڈائیلاگ دکھانا۔ Mock کے بغیر، حقیقی بنیادی ڈھانچہ چلائے بغیر ان تعاملات کی تصدیق نہیں کی جا سکتی۔ Google Testing Blog کے مطابق، ٹیسٹ سرور شروع کیے بغیر یہ تصدیق کرنے کا واحد طریقہ ہے کہ ایپلیکیشن نے واقعی analytics واقعہ بھیجا ہے۔

Mock بمقابلہ Stub: تفصیلی موازنہ

Mock اور Stub کے درمیان فرق ٹیسٹنگ میں سب سے زیادہ بحث کردہ موضوعات میں سے ایک ہے۔ دونوں اقسام حقیقی انحصار کو بدلتی ہیں، لیکن بنیادی طور پر مختلف طریقوں سے۔

معیارMockStub
بنیادی سوالکیا طریقہ کار بلایا گیا؟کون سا نتیجہ لوٹایا گیا؟
تصدیقرویہ (verify)حالت (assert)
ڈیٹا کی واپسیاختیاریلازمی
مثالverify(analytics).logEvent(“click”)assertEquals(5, repository.getCount())
کب استعمال کریںضمنی اثراتڈیٹا کی واپسی

عملی قاعدہ: Mock یا نہیں

فیصلے کے لیے ایک سادہ ٹیسٹ: اپنے آپ سے پوچھیں «اگر میں کوڈ کی یہ سطر حذف کروں، کیا ٹیسٹ ناکام ہوگا؟» اگر ٹیسٹ واپسی کی قیمت چیک کرتا ہے — آپ کو Stub (assert پر مبنی تصدیق) چاہیے۔ اگر ٹیسٹ چیک کرتا ہے کہ کوڈ نے صحیح دلائل کے ساتھ طریقہ کار بلایا — آپ کو Mock (verify پر مبنی تصدیق) چاہیے۔ یہ دوئی Command-Query Separation پیٹرن کی پیروی کرتی ہے: جو طریقہ کار حالت بدلتے ہیں (commands) انہیں Mock چاہیے؛ جو طریقہ کار ڈیٹا لوٹاتے ہیں (queries) انہیں Stub چاہیے۔

Mockito بمقابلہ MockK: لائبریری موازنہ

Mockito اور MockK کے درمیان انتخاب Kotlin میں Android پروجیکٹ کے ٹیسٹ اسٹیک کو ترتیب دیتے وقت پہلے فیصلوں میں سے ایک ہے۔ دونوں لائبریریاں ایک ہی مقصد پورا کرتی ہیں، لیکن Kotlin کی مخصوص خصوصیات کے لیے مختلف نقطہ نظر کے ساتھ۔

Mockito: ثابت شدہ کلاسک

Mockito Java پروجیکٹس کے لیے حقیقی معیار ہے۔ ورژن 5.x بلٹ ان MockMaker کی بدولت فائنل کلاسز، سٹیٹک طریقہ کار اور کنسٹرکٹرز کے لیے mocking کی حمایت کرتا ہے۔ Kotlin پروجیکٹس کے لیے، Mockito کو اضافی سیٹ اپ کی ضرورت ہے: بہتر نحو کے لیے mockito-kotlin ایکسٹینشنز، فائنل کلاسز کے لیے mockito-inline۔ Mockito اضافی اڈاپٹر کے بغیر Kotlin coroutine اور suspend فنکشنز کی حمایت نہیں کرتا۔

MockK: Kotlin-اول نقطہ نظر

MockK خاص طور پر Kotlin کے لیے بنایا گیا تھا۔ یہ مقامی طور پر coroutine (coEvery, coVerify)، sealed class، data class، آبجیکٹ سنگلٹن اور ایکسٹینشن فنکشنز کی حمایت کرتا ہے۔ MockK کا نحو لیمبڈا بلاکس کے ساتھ DSL استعمال کرتا ہے، جو Kotlin کوڈ میں قدرتی لگتا ہے۔ MockK اضافی سیٹ اپ کے بغیر پراپرٹی mocking کی بھی حمایت کرتا ہے — یہ Android پروجیکٹس کے لیے اہم ہے جو LiveData، StateFlow اور Delegates استعمال کرتے ہیں۔

kotlin
// Mockito + mockito-kotlin
val repository = mock<UserRepository>()
whenever(repository.getUser(1)).thenReturn(user)

// MockK
val repository = mockk<UserRepository>()
every { repository.getUser(1) } returns user

کارکردگی کا موازنہ

بینچ مارکس (JVM Benchmark, 2024) ظاہر کرتے ہیں کہ MockK Java Reflections کے بجائے براہ راست Kotlin بائٹ کوڈ کے ساتھ کام کرنے کی وجہ سے Kotlin پروجیکٹس کے لیے Mockito سے 15–20% تیزی سے mock اشیاء بناتا ہے۔ ہزاروں یونٹ ٹیسٹ والے پروجیکٹس کے لیے، بلڈ سپیڈ میں فرق نمایاں ہو سکتا ہے: MockK بڑے پروجیکٹس میں مکمل ٹیسٹ رن پر 30–60 سیکنڈ بچاتا ہے۔

Kotlin میں Mock ٹیسٹ کی مثالیں

تین منظرناموں کا جائزہ لیں: Mock انحصار کے ساتھ ViewModel کی جانچ، API کال کی تصدیق کے ساتھ UseCase کی جانچ، اور coVerify کے ساتھ coroutine کی جانچ۔

مثال 1: Mock analytics کے ساتھ ViewModel

kotlin
class ProfileViewModelTest {
    private val analytics = mockk<AnalyticsService>()
    private val repo = mockk<UserRepository>()
    private val vm = ProfileViewModel(repo, analytics)

    fun `profile opened logs analytics event`() {
        every { analytics.logEvent("profile_opened") } returns Unit

        vm.onViewCreated()

        verify { analytics.logEvent("profile_opened") }
    }
}

مثال 2: غیر متزامن تصدیق کے ساتھ UseCase

kotlin
class SendMessageUseCaseTest {
    private val api = mockk<MessagingApi>()
    private val useCase = SendMessageUseCase(api)

    fun `send message with correct payload`() = runTest {
        val message = Message(text = "Hello", userId = 42)

        coEvery { api.sendMessage(any()) } returns MessageResult.Sent("msg_1")

        val result = useCase.execute(message)

        coVerify {
            api.sendMessage(match {
                it.text == "Hello" && it.userId == 42
            })
        }
        assertTrue(result is MessageResult.Sent)
    }
}

مثال 3: ArgumentCaptor کے ساتھ دلیل کی تصدیق

kotlin
class OrderUseCaseTest {
    private val api = mockk<OrderApi>()
    private val useCase = OrderUseCase(api)
    private val slot = slot<OrderRequest>()

    fun `order request contains correct items`() = runTest {
        coEvery { api.placeOrder(capture(slot)) } returns OrderResult.Placed("order_1")

        useCase.execute(listOf("item_a", "item_b"))

        assertEquals(2, slot.captured.items.size)
        assertEquals("item_a", slot.captured.items[0])
    }
}

Mock ٹیسٹنگ کے بہترین طریقے

موبائل ڈیولپمنٹ میں Mock کا مؤثر استعمال نظم و ضبط کا تقاضا کرتا ہے۔ ان قواعد کی خلاف ورزی ٹیسٹوں کو نازک رکاوٹوں میں بدل دیتی ہے جو ہر ری فیکٹرنگ کے ساتھ ٹوٹ جاتے ہیں۔

صرف بیرونی ایپلیکیشن حدود کو Mock کریں

ایک سخت قاعدہ: Mock صرف ان انحصاروں کے لیے بنائے جانے چاہئیں جو ایپلیکیشن کی حد کو عبور کرتے ہیں: API کلائنٹس، ڈیٹابیسز، فائل سسٹم، سسٹم سروسز (LocationManager, BluetoothAdapter, Camera)۔ اندرونی ایپلیکیشن کلاسز — ڈومین اینٹیٹیز، Value Objects، سادہ یوٹیلیٹیز — کو Mock سے تبدیل نہیں کیا جانا چاہیے۔ ان کے رویے کی جانچ حقیقی اشیاء کے ذریعے کی جاتی ہے۔

فی ٹیسٹ ایک assert / verify

ہر ٹیسٹ میں بالکل ایک منطقی جانچ ہونی چاہیے — یا تو verify (Mock کے لیے) یا assert (Stub کے لیے)۔ ایک ہی ٹیسٹ میں حالت اور رویے کی تصدیق کو نہ ملائیں۔ اگر آپ کو API کال اور اس کے نتیجہ دونوں کی جانچ کرنی ہے — مختلف ناموں کے ساتھ دو الگ ٹیسٹ بنائیں۔ یہ قاعدہ، جو “فی ٹیسٹ ایک assert” کے نام سے جانا جاتا ہے، Kent Beck (2002) کی سفارشات سے آتا ہے۔

  • Unit لوٹانے والے طریقہ کار کے لیے MockK میں relaxUnitFun = true استعمال کریں — ورنہ Mock غیر متعین کال پر استثنا پھینکے گا
  • verify کو صرف اہم کالوں تک محدود رکھیں — ہر getter اور setter کی تصدیق نہ کریں، یہ ٹیسٹوں کو نازک بناتا ہے
  • ArgumentMatchers کو سمجھداری سے لگائیں — if the argument is critical for business logic, any() اہم تفصیلات چھپاتا ہے
  • verifyNoMoreInteractions کا ضرورت سے زیادہ استعمال نہ کریں — یہ طریقہ ٹیسٹوں کو پروڈکشن کوڈ میں کسی بھی تبدیلی کے لیے غیر ضروری طور پر سخت بناتا ہے
  • @MockkAnnotations استعمال کریں Mock اشیاء کی خودکار ابتدا کے لیے — یہ بائیلرپلیٹ کم کرتا ہے اور پڑھنے کی اہلیت بہتر کرتا ہے

Mock ٹیسٹنگ کی جدید تکنیکیں

بنیادی mocking کے علاوہ، جدید تکنیکیں ہیں جو موبائل ڈیولپمنٹ میں مخصوص کاموں کو حل کرتی ہیں: ملٹی تھریڈنگ کی جانچ، Flow حالت کی تصدیق اور حقیقی اشیاء کا جزوی mocking۔

spyK کے ساتھ جزوی Mock

Spy (یا جزوی mock) ایک شے بنانے کی اجازت دیتا ہے جو کالوں کو حقیقی نفاذ کو سونپتی ہے لیکن انفرادی طریقہ کار کو اوور رائڈ کرنے دیتی ہے۔ MockK میں، spyk ایک حقیقی کلاس مثال کی بنیاد پر بنایا جاتا ہے: val repo = spyk(InMemoryUserRepository())۔ every کے ذریعے متعین توقعات والی کالیں Mock سے گزرتی ہیں؛ باقی حقیقی شے سے گزرتی ہیں۔ Spy خاص طور پر پرانے کوڈ کی جانچ کے لیے مفید ہے جہاں انحصار کا انجیکشن ابھی لاگو نہیں ہوا ہے اور آپ کو صرف ایک طریقہ کار کو اوور رائڈ کرنے کی ضرورت ہے۔

Turbine کے ساتھ StateFlow کی جانچ

Jetpack Compose استعمال کرنے والے جدید Android پروجیکٹس میں، ViewModel StateFlow کے ذریعے حالت ظاہر کرتا ہے۔ MockK Flow انحصاروں کو mock کرنے کی اجازت دیتا ہے، اور Turbine لائبریری اخراج کی تصدیق کو آسان بناتی ہے۔ کلاسک پیٹرن: Flow لوٹانے والے UseCase کے لیے MockK، ViewModel کے اخراج کی تصدیق کے لیے Turbine۔ یہ اسٹیک Kotlin Coroutines استعمال کرنے والے پروجیکٹس کے لیے Android Testing دستاویزات (Google, 2024) کے ذریعے تجویز کردہ ہے۔

kotlin
class SearchViewModelTest {
    private val searchUseCase = mockk<SearchUseCase>()
    private val vm = SearchViewModel(searchUseCase)

    fun `search emits results`() = runTest {
        coEvery { searchUseCase.search("android") } returns
            flowOf(SearchResult.Success(listOf(Item("Android TDD"))))

        vm.search("android")

        vm.state.test {
            val state = awaitItem()
            assertTrue(state.items.isNotEmpty())
            cancelAndIgnoreRemainingEvents()
        }
    }
}

اکثر پوچھے گئے سوالات

Mock، Mockito سے کیسے مختلف ہے؟

Mock ایک تصور ہے، Test Double کی ایک قسم جو رویے کی تصدیق کرتی ہے۔ Mockito Java اور Android میں Mock اشیاء بنانے کے لیے ایک لائبریری ہے۔ دیگر لائبریریاں: MockK (Kotlin)، EasyMock (Java)، Cuckoo (iOS)۔

Mock Kotlin coroutine کے ساتھ کیسے کام کرتا ہے؟

Mock کے ساتھ suspend فنکشنز کی جانچ کے لیے MockK (coEvery / coVerify) یا mockito-kotlin کے ساتھ Mockito استعمال کریں۔ MockK coroutine کو مقامی طور پر سپورٹ کرتا ہے: coEvery ایک suspend فنکشن کے رویے کی وضاحت کرتا ہے، coVerify coroutine کے اندر اس کی کال کی تصدیق کرتا ہے۔ تمام suspend کالیں runTest (kotlinx-coroutines-test) کے اندر عمل میں آنی چاہئیں۔

کیا Mock بار بار کال کرنے پر مختلف قدریں لوٹا سکتا ہے؟

ہاں۔ MockK میں returnsMany استعمال کریں: every { api.getData() } returnsMany listOf(response1, response2)۔ Mockito میں — thenReturn(value1).thenReturn(value2) کا سلسلہ۔ یہ مختلف جوابات لوٹانے والی ترتیب وار کالوں کے ساتھ رویے کی جانچ کے لیے مفید ہے۔

ٹیسٹوں کے درمیان Mock کی حالت کیسے صاف کریں؟

MockK میں relaxed = true کے ساتھ @MockK اینوٹیشن استعمال کریں اور @After طریقہ کار میں clearMocks(mock) کال کریں۔ Mockito میں — Mockito.reset(mock)۔ بہترین عمل: ٹیسٹوں کے درمیان مداخلت ختم کرنے کے لیے @Before کے ذریعے ہر ٹیسٹ کے لیے نیا Mock بنائیں۔

Mock Kotlin میں sealed class کو کیسے ہینڈل کرتا ہے؟

MockK sealed class کے ساتھ صحیح طریقے سے کام کرتا ہے: every { useCase() } returns Result.Success(data)۔ Mockito براہ راست sealed class کو سپورٹ نہیں کرتا، جس کے لیے متبادل حل درکار ہیں۔ یہ ایک وجہ ہے کہ Kotlin پروجیکٹس کے لیے Mockito کے بجائے MockK تجویز کیا جاتا ہے۔

خلاصہ

  • Mock — Test Double کی ایک قسم جو انحصاروں کی حالت (assert) کے بجائے رویے (verify) کی تصدیق کرتی ہے
  • Mockito — Java/Android کے لیے معیار، MockK — coroutine اور sealed class کی حمایت کے ساتھ Kotlin-اول انتخاب
  • بنیادی قاعدہ: بیرونی حدود (نیٹ ورک، DB، سسٹم سروسز) کے لیے Mock، اندرونی کلاسز کے لیے حقیقی اشیاء
  • Over-mocking — اہم مخالف نمونہ: ضرورت سے زیادہ انحصار کی تبدیلی ٹیسٹوں کو نازک اور بے کار بناتی ہے
  • ایک ٹیسٹ — ایک منطقی جانچ: Mock کے لیے verify یا Stub کے لیے assert، ایک ہی ٹیسٹ میں دونوں نہیں
  • ArgumentCaptor / slot — اندھے any() کے بجائے Mock کال کے دلائل کی تصدیق کرنے کا صحیح طریقہ
  • Kotlin پروجیکٹس کے لیے MockK تجویز کردہ: coEvery اور coVerify اضافی اڈاپٹر کے بغیر coroutine کے ساتھ مقامی طور پر کام کرتے ہیں

ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے

IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں