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-এর বিকল্প, করুটিন এবং সিলড ক্লাসের জন্য নেটিভ সমর্থন সহ
  • Behavior verification — Mock এবং Stub-এর মধ্যে মূল পার্থক্য: Mock আচরণ যাচাই করে, অবস্থা নয়
  • Over-mocking — প্রধান অ্যান্টি-প্যাটার্ন: mock শুধুমাত্র বাহ্যিক নির্ভরতার জন্য হওয়া উচিত

Mock কী?

Mock হল একটি অবজেক্ট যা মকিং ফ্রেমওয়ার্ক (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।

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-এর কারণে ফাইনাল ক্লাস, স্ট্যাটিক পদ্ধতি এবং কনস্ট্রাক্টরের জন্য মকিং সমর্থন করে। Kotlin প্রকল্পের জন্য, Mockito-র অতিরিক্ত সেটআপ প্রয়োজন: উন্নত সিনট্যাক্সের জন্য mockito-kotlin এক্সটেনশন, ফাইনাল ক্লাসের জন্য mockito-inline। Mockito অতিরিক্ত অ্যাডাপ্টার ছাড়া Kotlin করুটিন এবং suspend ফাংশন সমর্থন করে না।

MockK: Kotlin-প্রথম দৃষ্টিভঙ্গি

MockK বিশেষভাবে Kotlin-এর জন্য তৈরি করা হয়েছিল। এটি নেটিভভাবে করুটিন (coEvery, coVerify), সিলড ক্লাস, ডেটা ক্লাস, অবজেক্ট সিঙ্গেলটন এবং এক্সটেনশন ফাংশন সমর্থন করে। MockK সিনট্যাক্স ল্যাম্বডা ব্লক সহ DSL ব্যবহার করে, যা Kotlin কোডে স্বাভাবিক মনে হয়। MockK অতিরিক্ত সেটআপ ছাড়াই প্রপার্টি মকিং সমর্থন করে — এটি 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% দ্রুত মক অবজেক্ট তৈরি করে। হাজার হাজার ইউনিট টেস্ট সহ প্রকল্পের জন্য, বিল্ড গতির পার্থক্য লক্ষণীয় হতে পারে: MockK বড় প্রকল্পে সম্পূর্ণ টেস্ট রানে 30–60 সেকেন্ড বাঁচায়।

Kotlin-এ Mock টেস্টের উদাহরণ

তিনটি দৃশ্যকল্প পরীক্ষা করা যাক: Mock নির্ভরতা সহ ViewModel টেস্টিং, API কল যাচাই সহ UseCase টেস্টিং, এবং coVerify সহ করুটিন টেস্টিং।

উদাহরণ 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)-এর সুপারিশ থেকে এসেছে।

  • MockK-এ Unit ফেরত দেওয়া পদ্ধতির জন্য relaxUnitFun = true ব্যবহার করুন — অন্যথায় Mock অনির্ধারিত কলএ ব্যতিক্রম ছুঁড়বে
  • verify শুধুমাত্র গুরুত্বপূর্ণ কলের মধ্যে সীমাবদ্ধ রাখুন — প্রতিটি getter এবং setter যাচাই করবেন না, এটি টেস্টকে ভঙ্গুর করে
  • ArgumentMatchers বুদ্ধিমানের সাথে প্রয়োগ করুন — any() গুরুত্বপূর্ণ বিবরণ লুকায় যদি আর্গুমেন্ট ব্যবসায়িক যুক্তির জন্য গুরুত্বপূর্ণ হয়
  • verifyNoMoreInteractions-এর অতিরিক্ত ব্যবহার করবেন না — এই পদ্ধতি টেস্টকে প্রোডাকশন কোডের যেকোনো পরিবর্তনের প্রতি অপ্রয়োজনীয়ভাবে কঠোর করে তোলে
  • @MockkAnnotations ব্যবহার করুন Mock অবজেক্টের স্বয়ংক্রিয় আরম্ভের জন্য — এটি বয়লারপ্লেট হ্রাস করে এবং পঠনযোগ্যতা উন্নত করে

Mock টেস্টিংয়ের উন্নত কৌশল

মৌলিক মকিং ছাড়াও, উন্নত কৌশল রয়েছে যা মোবাইল ডেভেলপমেন্টে নির্দিষ্ট কাজগুলি সমাধান করে: মাল্টিথ্রেডিং পরীক্ষা, Flow অবস্থা যাচাই এবং বাস্তব অবজেক্টের আংশিক মকিং।

spyK সহ আংশিক Mock

Spy (বা আংশিক mock) একটি অবজেক্ট তৈরি করতে দেয় যা বাস্তব বাস্তবায়নে কল ডেলিগেট করে কিন্তু পৃথক পদ্ধতি ওভাররাইড করতে দেয়। MockK-এ, spyk একটি বাস্তব ক্লাস ইনস্ট্যান্সের উপর ভিত্তি করে তৈরি করা হয়: val repo = spyk(InMemoryUserRepository())every-এর মাধ্যমে সংজ্ঞায়িত প্রত্যাশা সহ কলগুলি Mock-এর মাধ্যমে যায়; বাকিগুলি বাস্তব অবজেক্টের মাধ্যমে যায়। Spy বিশেষ করে লিগ্যাসি কোড পরীক্ষার জন্য উপযোগী যেখানে ডিপেন্ডেন্সি ইনজেকশন এখনও প্রয়োগ করা হয়নি এবং আপনার শুধুমাত্র একটি পদ্ধতি ওভাররাইড করতে হবে।

Turbine সহ StateFlow পরীক্ষা

Jetpack Compose ব্যবহারকারী আধুনিক Android প্রকল্পে, ViewModel StateFlow-এর মাধ্যমে অবস্থা প্রকাশ করে। MockK Flow নির্ভরতা মক করার অনুমতি দেয়, এবং 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 করুটিনের সাথে কীভাবে কাজ করে?

Mock-এর সাথে suspend ফাংশন পরীক্ষার জন্য MockK (coEvery / coVerify) বা mockito-kotlin সহ Mockito ব্যবহার করুন। MockK নেটিভভাবে করুটিন সমর্থন করে: coEvery একটি suspend ফাংশনের আচরণ সংজ্ঞায়িত করে, coVerify করুটিনের ভিতরে তার কল যাচাই করে। সমস্ত 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-এ সিলড ক্লাস কীভাবে হ্যান্ডেল করে?

MockK সিলড ক্লাসের সাথে সঠিকভাবে কাজ করে: every { useCase() } returns Result.Success(data)Mockito সরাসরি সিলড ক্লাস সমর্থন করে না, যার জন্য ওয়ার্কঅ্যারাউন্ড প্রয়োজন। এটি একটি কারণ কেন Kotlin প্রকল্পের জন্য Mockito-এর পরিবর্তে MockK সুপারিশ করা হয়।

সারসংক্ষেপ

  • Mock — একটি Test Double প্রকার যা নির্ভরতার আচরণ (verify) যাচাই করে, অবস্থা (assert) নয়
  • Mockito — Java/Android-এর জন্য মান, MockK — করুটিন এবং সিলড ক্লাসের সমর্থন সহ Kotlin-প্রথম পছন্দ
  • মূল নিয়ম: বাহ্যিক সীমানার জন্য Mock (নেটওয়ার্ক, DB, সিস্টেম পরিষেবা), অভ্যন্তরীণ ক্লাসের জন্য বাস্তব অবজেক্ট
  • Over-mocking — প্রধান অ্যান্টি-প্যাটার্ন: অত্যধিক নির্ভরতা প্রতিস্থাপন টেস্টকে ভঙ্গুর এবং অকেজো করে
  • একটি টেস্ট — একটি যৌক্তিক পরীক্ষা: Mock-এর জন্য verify বা Stub-এর জন্য assert, একই টেস্টে উভয় নয়
  • ArgumentCaptor / slot — অন্ধ any()-এর পরিবর্তে Mock কল আর্গুমেন্ট যাচাইয়ের সঠিক উপায়
  • Kotlin প্রকল্পের জন্য MockK সুপারিশ করা হয়: coEvery এবং coVerify অতিরিক্ত অ্যাডাপ্টার ছাড়াই নেটিভভাবে করুটিনের সাথে কাজ করে

আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব

IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।

প্রকল্প নিয়ে আলোচনা করুন

আরও পড়ুন