दिलचस्प पोस्ट
Python int और लंबे समय कैसे प्रबंधित करता है? मैप दृश्य में एक एनोटेशन के रूप में मैं UIPopoverView कैसे प्रदर्शित करूं? (आईपैड) मॉड्यूलस ऑपरेटर जावास्क्रिप्ट में आंशिक संख्या क्यों देता है? एक अन्य संरचना के साथ संरचना निर्दिष्ट करें एनजी-एप और डेटा-एनजी-एप के बीच अंतर क्या है? जब अभ्यर्पण विफल हुआ है, तो निष्पादन को कैसे जारी किया जाए कैसे एक सही MySQL कनेक्शन स्ट्रिंग बनाने के लिए? रिक्त स्थान के साथ std :: cin इनपुट? प्राथमिकता प्रश्न। गलत तत्व क्रमांतरण मर्ज पर व्हाइसेस्पेस को कैसे निकालें एक WHERE खंड में उपनाम का उपयोग करना जावा स्विंग में एक छवि प्रदर्शित करना कॉलम चौड़ाई को शून्य पर सेट नहीं कर सका, अर्थात अदृश्य नहीं किया गया स्तंभ घोंसले के शिकार एनजी-कोयले जेएस में विचार प्लगइन मान्य jQuery: केवल पत्र स्वीकार करते हैं?

अमूर्त वर्गों का परीक्षण करने के लिए मोकिटो का उपयोग करना

मैं एक अमूर्त वर्ग का परीक्षण करना चाहता हूँ ज़रूर, मैं मैन्युअल रूप से एक नकली लिख सकता हूं जो कक्षा से निकलता है।

क्या मैं यह कर सकता हूँ कि मेरी नकली हाथों की जगह मज़ेदार ढांचे का उपयोग कर (मैं मॉकिटो का उपयोग कर रहा हूं)? कैसे?

Solutions Collecting From Web of "अमूर्त वर्गों का परीक्षण करने के लिए मोकिटो का उपयोग करना"

निम्नलिखित सुझाव के आधार पर आप "असली" उप-वर्ग के बिना सार वर्गों का परीक्षण करते हैं – नकली उप-वर्ग है

Mockito.mock(My.class, Mockito.CALLS_REAL_METHODS) उपयोग करें, फिर किसी भी अमूर्त तरीकों का Mockito.mock(My.class, Mockito.CALLS_REAL_METHODS) जिन्हें लागू किया गया है।

उदाहरण:

 public abstract class My { public Result methodUnderTest() { ... } protected abstract void methodIDontCareAbout(); } public class MyTest { @Test public void shouldFailOnNullIdentifiers() { My my = Mockito.mock(My.class, Mockito.CALLS_REAL_METHODS); Assert.assertSomething(my.methodUnderTest()); } } 

नोट: इस समाधान की सुंदरता यह है कि आपको अमूर्त विधियों को कार्यान्वित करने की आवश्यकता नहीं है , जब तक कि वे कभी भी लागू नहीं होते हैं।

मेरी ईमानदार राय में, यह एक जासूस का उपयोग करने से निपुण है, क्योंकि एक जासूस को एक उदाहरण की आवश्यकता होती है, जिसका अर्थ है कि आपको अपने सार वर्ग के एक तत्कालीन subclass बनाना होगा।

यदि आपको किसी भी संक्षेप को छूने के बिना कुछ ठोस तरीकों का परीक्षण करने की आवश्यकता है, तो आप CALLS_REAL_METHODS ( Morten का उत्तर देखें) का उपयोग कर सकते हैं, लेकिन अगर टेस्ट के तहत कंक्रीट विधि कुछ CALLS_REAL_METHODS , या क्रियान्वित नहीं किए गए इंटरफ़ेस विधियों को बताती है, तो यह नहीं होगा काम – मोकीटो शिकायत करेगा "जावा इंटरफेस पर वास्तविक तरीके से कॉल नहीं किया जा सकता है।"

(हां, यह एक घटिया डिजाइन है, लेकिन कुछ चौखटे, जैसे टेपेस्ट्री 4, इसे आप पर बल।)

इस दृष्टिकोण को रिवर्स करना है – सामान्य नकली व्यवहार का उपयोग करें (यानी, सबकुछ की doCallRealMethod() / doCallRealMethod() ) और उपयोग doCallRealMethod() को स्पष्ट रूप से टेस्ट के तहत कंक्रीट विधि को कॉल करने के लिए। उदाहरण के लिए

 public abstract class MyClass { @SomeDependencyInjectionOrSomething public abstract MyDependency getDependency(); public void myMethod() { MyDependency dep = getDependency(); dep.doSomething(); } } public class MyClassTest { @Test public void myMethodDoesSomethingWithDependency() { MyDependency theDependency = mock(MyDependency.class); MyClass myInstance = mock(MyClass.class); // can't do this with CALLS_REAL_METHODS when(myInstance.getDependency()).thenReturn(theDependency); doCallRealMethod().when(myInstance).myMethod(); myInstance.myMethod(); verify(theDependency, times(1)).doSomething(); } } 

जोड़ने के लिए अपडेट किया गया:

गैर-रहित तरीकों के लिए, आपको इसके बजाय thenCallRealMethod() उपयोग करना होगा, जैसे:

 when(myInstance.myNonVoidMethod(someArgument)).thenCallRealMethod(); 

अन्यथा मॉकिटो शिकायत करेगा "अधूरा छिड़काव का पता चला।"

आप इसे एक जासूस का उपयोग कर प्राप्त कर सकते हैं (यद्यपि मोकीकी 1.8+ के नवीनतम संस्करण का उपयोग करें)।

 public abstract class MyAbstract { public String concrete() { return abstractMethod(); } public abstract String abstractMethod(); } public class MyAbstractImpl extends MyAbstract { public String abstractMethod() { return null; } } // your test code below MyAbstractImpl abstractImpl = spy(new MyAbstractImpl()); doReturn("Blah").when(abstractImpl).abstractMethod(); assertTrue("Blah".equals(abstractImpl.concrete())); 

चौंकाने वाले ढांचे को तैयार किया गया है जिससे आप परीक्षण कर रहे वर्ग की निर्भरता को बेकार कर सकते हैं। जब आप कक्षा को नकल करने के लिए एक मस्तूल ढांचे का उपयोग करते हैं, तो अधिकांश ढांचे गतिशील रूप से एक उपवर्ग बनाते हैं, और पद्धति को कार्यान्वित करते समय विधि के कार्यान्वयन को एक विधि को बुलाया जाता है और नकली मूल्य लौटाता है।

एक अमूर्त वर्ग का परीक्षण करते समय, आप परीक्षा के अंतर्गत विषय (एसयूटी) के गैर-अमूर्त तरीकों को निष्पादित करना चाहते हैं, इसलिए एक मजाकिया ढांचे आपको नहीं चाहिए।

भ्रम का हिस्सा यह है कि जिस प्रश्न से आपने जुड़ा हुआ है, उसका उत्तर आपके अमूर्त वर्ग से फैला हुआ नकली हाथ से करता है। मैं ऐसी कक्षा को एक मजाक नहीं कहूंगा एक नकली एक वर्ग है जिसे निर्भरता के लिए प्रतिस्थापन के रूप में प्रयोग किया जाता है, उम्मीदों के साथ क्रमादेशित है, और यह देखने के लिए पूछताछ की जा सकती है कि क्या उन उम्मीदों को पूरा किया गया है या नहीं।

इसके बजाय, मैं सुझाव देता हूं कि आपके परीक्षण में आपके सार वर्ग के एक गैर-अमूर्त उप-वर्ग को परिभाषित करें। यदि यह बहुत अधिक कोड में परिणाम है, तो इससे एक संकेत हो सकता है कि आपकी कक्षा का विस्तार करना मुश्किल है।

एक वैकल्पिक समाधान अपने परीक्षण के मामले को सार बनाने के लिए होगा, ताकि सट बनाने के लिए एक सार विधि के साथ (दूसरे शब्दों में, टेस्ट केस टेम्प्लेट मेथड डिज़ाइन पैटर्न का उपयोग करेगा)।

कस्टम उत्तर का उपयोग करने की कोशिश करें

उदाहरण के लिए:

 import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; public class CustomAnswer implements Answer<Object> { public Object answer(InvocationOnMock invocation) throws Throwable { Answer<Object> answer = null; if (isAbstract(invocation.getMethod().getModifiers())) { answer = Mockito.RETURNS_DEFAULTS; } else { answer = Mockito.CALLS_REAL_METHODS; } return answer.answer(invocation); } } 

यह अमूर्त विधियों के लिए नकली लौटाएगा और ठोस विधियों के लिए वास्तविक पद्धति को बुलाएगा।

क्या वास्तव में मुझे अमूर्त वर्गों का मजाक करने के बारे में बुरा लगता है, यह तथ्य है कि न तो डिफ़ॉल्ट कन्स्ट्रक्टर आपका ऐबस्ट्रैकक्लस () को बेवकूफ़ बनाकर (लापता सुपर ()) कहा जाता है और न ही नकली गुणों को प्रारंभ करने के लिए मॉकिटो में किसी भी तरह से प्रतीत होता है (जैसे सूची गुण खाली ArrayList या LinkedList के साथ)

मेरा अमूर्त वर्ग (मूल तौर पर वर्ग स्रोत कोड उत्पन्न होता है) सूची तत्वों के लिए निर्भरता सेटर इंजेक्शन प्रदान नहीं करता है, और न ही एक कन्स्ट्रक्टर जहां वह सूची तत्वों को आरंभ करता है (जो मैंने मैन्युअल रूप से जोड़ने का प्रयास किया था)।

केवल क्लास विशेषताएं डिफ़ॉल्ट आरंभीकरण का उपयोग करती हैं: निजी सूची dep1 = नए अर्रेइस्ट; निजी सूची dep2 = नया अर्रेलिस्ट

इसलिए वास्तविक वस्तु कार्यान्वयन (जैसे इकाई परीक्षण वर्ग में आंतरिक कक्षा परिभाषा, सार विधियों को अधिरोपित करने) और असली वस्तु (जो उचित फ़ील्ड प्रारंभ होता है) पर जासूसी किए बिना एक अमूर्त वर्ग का नकली तरीका नहीं है।

बहुत बुरा है कि केवल पावरमॉक यहां आगे मदद करेगा।

अपने परीक्षण वर्गों को मानते हुए एक ही पैकेज में (एक अलग स्रोत रूट के तहत) परीक्षण के तहत अपनी कक्षाओं के रूप में आप बस नकली बना सकते हैं:

 YourClass yourObject = mock(YourClass.class); 

और उन विधियों को बुलाओ जिन्हें आप परीक्षण करना चाहते हैं, जैसा कि आप किसी भी अन्य तरीके से करेंगे

आपको प्रत्येक विधि के लिए अपेक्षाओं को प्रदान करना होगा जो सुपर विधि को बुलाए गए ठोस तरीकों पर अपेक्षा के साथ बुलाया जाता है – सुनिश्चित नहीं है कि आप मोकीटो के साथ कैसे करते हैं, लेकिन मुझे विश्वास है कि EasyMock के साथ संभव है

यह सब आप के एक ठोस उदाहरण का निर्माण कर रहा है और आपको प्रत्येक सार पद्धति के खाली कार्यान्वयन के प्रयासों की बचत कर रहा है।

एक तरफ, मैं अक्सर अपने परीक्षण में अमूर्त वर्ग को लागू करने के लिए उपयोगी पाया जाता हूं, जहां यह एक उदाहरण कार्यान्वयन के रूप में कार्य करता है जिसे मैं अपने सार्वजनिक इंटरफ़ेस के माध्यम से परीक्षण करता हूं, हालांकि यह सार वर्ग द्वारा प्रदान की जाने वाली कार्यक्षमता पर निर्भर करता है।

आप अपने परीक्षण में अज्ञात वर्ग के साथ अमूर्त वर्ग का विस्तार कर सकते हैं। उदाहरण के लिए (जून 4 का उपयोग कर):

 private AbstractClassName classToTest; @Before public void preTestSetup() { classToTest = new AbstractClassName() { }; } // Test the AbstractClassName methods. 

आप एक गुमनाम वर्ग को इन्स्तांत कर सकते हैं, अपने मोजे को इंजेक्ट कर सकते हैं और फिर उस क्लास की जांच कर सकते हैं।

 @RunWith(MockitoJUnitRunner.class) public class ClassUnderTest_Test { private ClassUnderTest classUnderTest; @Mock MyDependencyService myDependencyService; @Before public void setUp() throws Exception { this.classUnderTest = getInstance(); } private ClassUnderTest getInstance() { return new ClassUnderTest() { private ClassUnderTest init( MyDependencyService myDependencyService ) { this.myDependencyService = myDependencyService; return this; } @Override protected void myMethodToTest() { return super.myMethodToTest(); } }.init(myDependencyService); } } 

ध्यान रखें कि दृश्यता को अमूर्त वर्ग ClassUnderTest की संपत्ति myDependencyService के लिए protected किया जाना चाहिए