Mockito एक ओपन-सोर्स फ्रेमवर्क है जो Java और Kotlin यूनिट परीक्षणों में mock-ऑब्जेक्ट बनाने के लिए है, जो परीक्षण किए जा रहे कोड को बाहरी निर्भरताओं से अलग करने की अनुमति देता है। इसकी मदद से, डेवलपर वास्तविक रिपॉजिटरी, API क्लाइंट और डेटाबेस को नियंत्रित स्टब से बदल देता है जिनका पूर्वनिर्धारित व्यवहार होता है। Mockito.org के अनुसार, यह लाइब्रेरी यूनिट परीक्षण का उपयोग करने वाले 60% से अधिक Java प्रोजेक्ट्स में उपयोग की जाती है।
मुख्य बिंदु
Mockito Java, Kotlin और अन्य JVM भाषाओं में यूनिट परीक्षणों के लिए mock-ऑब्जेक्ट (स्टब) बनाने वाली एक ओपन-सोर्स लाइब्रेरी है। JUnit के विपरीत, जो परीक्षण निष्पादन के लिए जिम्मेदार है, Mockito अलगाव की समस्या को हल करता है — यह परीक्षण की जा रही क्लास की वास्तविक निर्भरताओं को पूर्वानुमानित ऑब्जेक्ट से बदल देता है।
बिना mock के, किसी ऐसी विधि का परीक्षण करना जो डेटाबेस या बाहरी API तक पहुँचती है, वास्तविक वातावरण स्थापित करने की आवश्यकता होती है — डेटाबेस तैनात करना, सर्वर शुरू करना। Mockito इन निर्भरताओं को निश्चित व्यवहार वाले ऑब्जेक्ट से बदल देता है: repository.findById(1) विधि हमेशा एक निर्दिष्ट User ऑब्जेक्ट लौटाती है बिना डेटाबेस तक पहुँचे।
Mockito की आर्किटेक्चर Proxy पैटर्न (इंटरफ़ेस और क्लास के लिए) पर आधारित है। लाइब्रेरी निर्दिष्ट प्रकार के लिए एक उपवर्ग या प्रॉक्सी उत्पन्न करती है और सभी विधि कॉल को इंटरसेप्ट करती है, डिफ़ॉल्ट मान या when().thenReturn() के माध्यम से निर्धारित मान लौटाती है।
Mockito के काम करने का सिद्धांत तीन बुनियादी संक्रियाओं पर आधारित है: mock बनाना, व्यवहार कॉन्फ़िगर करना (stubbing) और कॉल की जाँच करना (verification)। प्रत्येक संक्रिया org.mockito.Mockito क्लास से स्थैतिक विधियों का उपयोग करती है — यह Maven Central के आँकड़ों के अनुसार Java इकोसिस्टम में सबसे अधिक डाउनलोड की जाने वाली क्लास है। सभी mock विधि कॉल मेमोरी में रिकॉर्ड की जाती हैं, जो बाद में verify के माध्यम से जाँच की अनुमति देती हैं।
Mockito के साथ एक सामान्य परीक्षण तीन चरणों से बना होता है: Arrange — when().thenReturn() के माध्यम से mock बनाना और स्टब कॉन्फ़िगर करना, Act — परीक्षण की जा रही विधि को कॉल करना, Assert — assertEquals और verify(mock) के माध्यम से परिणाम की जाँच करना। इस दृष्टिकोण को AAA (Arrange-Act-Assert) कहा जाता है।
एक सरल परीक्षण देखें जहाँ Mockito उपयोगकर्ता रिपॉजिटरी को बदल देता है। when().thenReturn() विधि mock को इस प्रकार कॉन्फ़िगर करती है कि findById कॉल पूर्व-तैयार User ऑब्जेक्ट लौटाए।
// रिपॉजिटरी mock बनाना
UserRepository mockRepo = mock(UserRepository.class);
// व्यवहार कॉन्फ़िगर करना: findById(1) उपयोगकर्ता लौटाता है
when(mockRepo.findById(1)).thenReturn(new User("Alice"));
// जाँचना कि विधि वास्तव में कॉल की गई थी
User result = mockRepo.findById(1);
assertEquals("Alice", result.getName());
verify(mockRepo).findById(1);
Mockito mock बनाने के दो तरीके प्रदान करता है: स्थैतिक विधि mock(Class) और @Mock एनोटेशन MockitoAnnotations.openMocks() के माध्यम से आरंभीकरण के साथ। पहला तरीका एक या दो mock के लिए कॉम्पैक्ट है, दूसरा तब सुविधाजनक है जब कई निर्भरताएँ हों — एनोटेशन boilerplate कोड को कम करते हैं।
mock() विधि एक क्लास लेती है और एक स्टब ऑब्जेक्ट लौटाती है जिसे when().thenReturn() के माध्यम से कॉन्फ़िगर किया जा सकता है। सभी अकॉन्फ़िगर विधियाँ डिफ़ॉल्ट मान लौटाती हैं: संख्याओं के लिए 0, boolean के लिए false, ऑब्जेक्ट के लिए null।
ApiClient apiClient = mock(ApiClient.class);
Database database = mock(Database.class);
@Mock एनोटेशन @ExtendWith(MockitoExtension.class) के साथ मिलकर परीक्षण क्लास के सभी फ़ील्ड के लिए स्वचालित रूप से mock बनाता है। MockitoExtension प्रत्येक परीक्षण से पहले आरंभीकरण के लिए जिम्मेदार है।
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@Test
void getUserShouldReturnUserFromRepo() {
when(userRepository.findById(1)).thenReturn(new User("Alice"));
User result = userService.getUser(1);
assertEquals("Alice", result.getName());
}
}
Stubbing यह परिभाषित करने की प्रक्रिया है कि mock विधि को विशिष्ट आर्गुमेंट के साथ कॉल करने पर क्या लौटाना चाहिए। मूल सिंटैक्स: when(mock.method(args)).thenReturn(value)। विभिन्न परिदृश्यों के लिए, Mockito कई then-विधि वेरिएंट प्रदान करता है।
| विधि | उद्देश्य |
|---|---|
| thenReturn(value) | हमेशा निर्दिष्ट मान लौटाती है |
| thenThrow(exception) | कॉल करने पर अपवाद फेंकती है |
| thenAnswer(answer) | गतिशील रूप से रिटर्न वैल्यू की गणना करती है |
| thenCallRealMethod() | वास्तविक विधि को कॉल करती है (आंशिक mock) |
जब रिटर्न वैल्यू कॉल आर्गुमेंट पर निर्भर करती है, तो lambda के साथ thenAnswer का उपयोग किया जाता है। यह वास्तविक डेटा के साथ काम का अनुकरण करने के लिए उपयोगी है — उदाहरण के लिए, पारित ऑब्जेक्ट के आधार पर ID जनरेट करना।
when(repository.save(any())).thenAnswer(invocation -> {
User user = invocation.getArgument(0);
user.setId(42);
return user;
});
Verify Mockito की एक अनूठी विशेषता है जो पुरानी mock-ऑब्जेक्ट लाइब्रेरीज़ (EasyMock, jMock) प्रदान नहीं करती हैं।
Verify परीक्षणों को अधिक विश्वसनीय बनाता है क्योंकि यह न केवल रिटर्न वैल्यू बल्कि साइड इफ़ेक्ट की भी जाँच करता है — उन विधियों की कॉल जो परिणाम नहीं लौटाती हैं (void विधियाँ)। verify(mock).methodName(args) विधि जाँचती है कि क्या एक निर्दिष्ट mock विधि को दिए गए आर्गुमेंट के साथ कॉल किया गया था। यह न केवल परिणाम बल्कि प्रक्रिया की भी जाँच करने की अनुमति देता है — निर्भरता तक पहुँचने का तथ्य।
डिफ़ॉल्ट रूप से, verify जाँचता है कि विधि को ठीक एक बार कॉल किया गया था। यदि भिन्न संख्या की आवश्यकता है, तो times(n), atLeast(n), never() और Mockito क्लास के अन्य मॉडिफ़ायर का उपयोग किया जाता है।
// कॉल की संख्या जाँचना
verify(repository, times(3)).save(any());
verify(repository, never()).delete(any());
verify(repository, atLeastOnce()).findById(1);
// कॉल के क्रम की जाँचना
InOrder inOrder = inOrder(repository);
inOrder.verify(repository).save(any());
inOrder.verify(repository).flush();
जब आपको यह जाँचने की आवश्यकता है कि विधि को किस ऑब्जेक्ट के साथ कॉल किया गया था, तो ArgumentCaptor का उपयोग किया जाता है। यह कॉल के दौरान आर्गुमेंट मान को कैप्चर करता है और इसके फ़ील्ड की अलग-अलग जाँच करने की अनुमति देता है। ArgumentCaptor विशेष रूप से तब उपयोगी होता है जब परीक्षण किया जा रहा कोड आंतरिक रूप से एक ऑब्जेक्ट बनाता है और इसे निर्भरता में पास करता है — आप उस ऑब्जेक्ट की अन्यथा जाँच नहीं कर सकते।
ArgumentCaptor<User> captor = ArgumentCaptor.forClass(User.class);
verify(repository).save(captor.capture());
assertEquals("Alice", captor.getValue().getName());
@Mock और @InjectMocks दो प्रमुख Mockito एनोटेशन हैं जो boilerplate कोड को काफी कम करते हैं। @Mock एक फ़ील्ड के लिए mock बनाता है, और @InjectMocks परीक्षण क्लास से सभी mock को परीक्षण किए जा रहे ऑब्जेक्ट में कंस्ट्रक्टर, सेटर या फ़ील्ड के माध्यम से इंजेक्ट करता है।
@InjectMocks तंत्र निम्नलिखित क्रम में निर्भरताओं को इंजेक्ट करने का प्रयास करता है: सबसे अधिक आर्गुमेंट वाला कंस्ट्रक्टर, प्रकार के अनुसार सेटर, प्राइवेट फ़ील्ड। यदि इनमें से कोई भी तरीका काम नहीं करता है, तो ऑब्जेक्ट null निर्भरताओं के साथ रहता है, और परीक्षण NullPointerException के साथ विफल हो जाएगा।
यह समझना महत्वपूर्ण है: @InjectMocks फ़ील्ड प्रकारों का विश्लेषण नहीं करता है — यह प्रकार से संगत किसी भी mock को प्रतिस्थापित करता है। यदि एक क्लास में एक ही प्रकार के दो फ़ील्ड हैं, तो Mockito गलत mock इंजेक्ट कर सकता है। ऐसे मामलों में, mock पैरामीटर के साथ स्पष्ट कंस्ट्रक्टर का उपयोग करने की अनुशंसा की जाती है।
Android डेवलपमेंट में, Mockito का उपयोग JUnit के साथ ViewModel, Repository और UseCase के परीक्षण के लिए किया जाता है। चूँकि ये क्लास Android संदर्भ के बिना JVM पर चलती हैं, Mockito उनकी निर्भरताओं — Room DAO, Retrofit API, SharedPreferences — को पूर्वानुमानित व्यवहार वाले स्टब से बदल देता है।
Android प्रोजेक्ट में Mockito जोड़ने के लिए, बस mockito-core या mockito-inline निर्भरता जोड़ें (बाद वाली फ़ाइनल क्लास और स्थैतिक विधियों के mocking का समर्थन करती है)। संस्करण 5.12.0 (2024) में Java 21 समर्थन और बेहतर JUnit 5 एकीकरण शामिल है।
// build.gradle.kts (module)
dependencies {
testImplementation("org.mockito:mockito-core:5.12.0")
testImplementation("org.mockito:mockito-junit-jupiter:5.12.0")
}
पहले, स्थैतिक विधियों और कंस्ट्रक्टरों के mocking के लिए PowerMock की आवश्यकता होती थी — एक एक्सटेंशन जो बाइटकोड इंस्ट्रूमेंटेशन के माध्यम से काम करता था। Mockito 5.x से mockito-inline के साथ, यह क्षमता सीधे अंतर्निहित है: mockStatic(ClassName.class) अतिरिक्त लाइब्रेरी के बिना स्थैतिक विधियों के mocking की अनुमति देता है।
एक सामान्य परिदृश्य: एक ViewModel रिपॉजिटरी विधि को कॉल करता है और परिणाम को UI स्थिति में बदलता है। Mockito रिपॉजिटरी को बदल देता है, और परीक्षण जाँचता है कि ViewModel सफल प्रतिक्रिया और त्रुटि दोनों को सही ढंग से संभालता है। Clean Architecture का उपयोग करते समय, प्रत्येक परत के लिए mock बनाए जाते हैं: DataSource, Repository और UseCase — यह प्रत्येक परत को अलग-अलग परीक्षण करने की अनुमति देता है।
अक्सर पूछे जाने वाले प्रश्न
Mockito Java और Kotlin के लिए एक लाइब्रेरी है जो प्रॉक्सी और रिफ्लेक्शन का उपयोग करती है। MockK एक Kotlin-first लाइब्रेरी है जो बिना अतिरिक्त कॉन्फ़िगरेशन के कोरूटीन, एक्सटेंशन फ़ंक्शन और फ़ाइनल क्लास का समर्थन करती है।
Mockito 2.1 से शुरू करके, फ़ाइनल क्लास का mocking opt-in के माध्यम से समर्थित है। संस्करण 5.x (mockito-inline) में, यह डिफ़ॉल्ट रूप से सक्षम है। बस mockito-inline निर्भरता जोड़ें और मानक mock() विधि का उपयोग करें।
Spy एक आंशिक mock है जो डिफ़ॉल्ट रूप से वास्तविक विधियों को कॉल करता है लेकिन when().thenReturn() के माध्यम से उनमें से कुछ को ओवरराइड करने की अनुमति देता है। Spy लीगेसी कोड के परीक्षण के लिए उपयोगी है जब पूरी क्लास को फिर से नहीं लिखा जा सकता।
thenReturn हमेशा आर्गुमेंट की परवाह किए बिना एक ही मान लौटाता है। thenAnswer इनवोकेशन — कॉल आर्गुमेंट, mock स्वयं और स्थिति के आधार पर रिटर्न वैल्यू की गणना करता है। गतिशील प्रतिक्रियाओं के लिए, हमेशा thenAnswer का उपयोग करें।
Verify न केवल परिणाम बल्कि प्रक्रिया की भी जाँच करता है — निर्भरता तक पहुँचने का तथ्य। यह उन सेवाओं के लिए महत्वपूर्ण है जिन्हें डेटा सहेजना या सूचनाएँ भेजनी होती हैं। Verify के बिना, परीक्षण यह पता नहीं लगाएगा कि किसी विधि ने save() या send() को कॉल नहीं किया।
सारांश
हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे
IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।
यह भी पढ़ें