2009-07-23 13 views
34

क्या एक मॉक ऑब्जेक्ट बनाना संभव है जो EasyMock के साथ कई इंटरफेस लागू करता है?क्या एक मॉक ऑब्जेक्ट बनाना संभव है जो EasyMock के साथ कई इंटरफेस लागू करता है?

उदाहरण के लिए, इंटरफ़ेस Foo और इंटरफ़ेस Closeable?

राइनो मोक्स में आप नकली वस्तु बनाते समय कई इंटरफेस प्रदान कर सकते हैं, लेकिन EasyMock की createMock() विधि केवल एक प्रकार लेती है।

क्या यह Foo और Closeable दोनों को विस्तारित करता है, और फिर उस पर मजाक कर रहा है, जो एक अस्थायी इंटरफ़ेस बनाने के पतन के बिना EasyMock के साथ इसे प्राप्त करने के लिए संभव है?

interface Bar extends Foo, Closeable { 
} 

और फिर नकली इंटरफ़ेस बार:

उत्तर

10

EasyMock इसका समर्थन नहीं करता है, इसलिए आप अस्थायी इंटरफ़ेस के फ़ॉलबैक के साथ फंस गए हैं।

एक तरफ के रूप में, मुझे एक कोड विफ़ की थोड़ी सी गंध आती है - क्या इस विधि में वास्तव में किसी ऑब्जेक्ट को 2 अलग-अलग चीजों, Foo और Closeable इंटरफ़ेस के रूप में व्यवहार करना चाहिए?

यह मेरा तात्पर्य है कि यह विधि कई परिचालन कर रही है और मुझे संदेह है कि उन परिचालनों में से एक Closeable को 'बंद' करना है, क्या यह कॉलिंग कोड को यह तय करने के लिए और अधिक समझ में नहीं आता कि 'बंद करें' ' आवश्यक है?

कोड इस तरह से 'खुला' और 'बंद' एक ही try ... finally ब्लॉक में रहता है और IMHO कोड अधिक का उल्लेख नहीं है पठनीय विधि अधिक सामान्य बनाता है और आप वस्तुओं है कि केवल Foo लागू गुजरने की अनुमति देता संरचना तैयार करना।

+4

मैं इसके साथ सहमत हूं, लेकिन विस्तार करने के लिए: यदि आप उपयोग कर रहे हैं निर्भरता इंजेक्शन, और आपकी कक्षा को एक फू और एक क्लोजेबल दोनों की आवश्यकता है, आपको वास्तव में उन लोगों के लिए दो अलग-अलग सेटर्स होना चाहिए। यदि आप इन दोनों के लिए एक ही वस्तु को इंजेक्ट करना चुनते हैं, तो महान, लेकिन मुझे लगता है कि कक्षा-अंडर-टेस्ट को यह जानने की आवश्यकता नहीं है कि वे एक ही वस्तु हैं - इसे फू को फू और क्लोजेबल के रूप में देखना चाहिए एक बंद करने योग्य –

+0

निक, मैट, आपके इनपुट के लिए धन्यवाद। परिदृश्य को स्पष्ट करने के लिए, संदर्भ यह है कि फू मॉड्यूलर ऐड-इन सिस्टम के लिए एक इंटरफ़ेस है। तीसरे पक्ष के मॉड्यूल फू को लागू करते हैं और फिर तत्काल और ढांचे द्वारा उपयोग किए जाते हैं। वे वैकल्पिक रूप से क्लोजेबल को भी कार्यान्वित कर सकते हैं, जिस स्थिति में ढांचे का उपयोग करके उन्हें बंद कर दिया जाएगा। इसलिए, यूनिट परीक्षणों को दो अलग-अलग परिदृश्यों को कवर करने की आवश्यकता होती है: एक फू जो बंद करने योग्य भी है, और एक फू जो बंद करने योग्य नहीं है। मुझे लगता है कि इसका मतलब बनता है। –

+1

@ निकहोल्ट: मैं आपसे पूरी तरह सहमत नहीं हूं। उस मामले पर विचार करें जब आपके पास इंटरफ़ेस 'व्यक्ति' है जिसमें केवल गेटर्स ('getFirstName()', get getddress() ', ...) और इंटरफ़ेस 'ModifiablePerson' है, जिसमें केवल सेटर्स (' setFirstName()', ' सेट एड्रेस() ', ...)। और अब आप एक एसयूटी का परीक्षण करना चाहते हैं, जो 'व्यक्ति' लेता है, लेकिन संशोधित ऑब्जेक्ट 'मॉडिफायबल पर्सन' का उदाहरण देता है और उस पर आधारित कुछ करता है। 'क्लोजेबल' भी एक अच्छा उदाहरण है: यदि ऑब्जेक्ट एक "विस्तारित" कार्यक्षमता प्रदान करता है, जिसे स्पष्ट रूप से 'exampleof' द्वारा चेक किया गया है और इसका लाभ उठाया गया है, तो इसमें क्या बुरा है? –

13

आप की तरह कुछ पर विचार किया है?

+1

हाँ, मैं सिर्फ अगर देख रहा था मैं इससे बच सकता था। मेरे प्रश्न के अनुसार: "क्या यह इज़ीमॉक के साथ इसे हासिल करने के लिए संभव है, एक अस्थायी इंटरफ़ेस बनाने के फॉलबैक का उपयोग किए बिना, जो फू और क्लोजेबल दोनों को बढ़ाता है, और फिर उस पर मज़ाक कर रहा है?" –

+0

मुझे यह समाधान पसंद है - टेस्ट क्लास में ऐसा इंटरफ़ेस बनाने के लिए मेरे लिए ठीक है, अच्छा विचार ;-) – Betlista

+0

ओपी की इच्छा बिल्कुल ठीक नहीं है लेकिन यह काम करता है :) –

2

मेरे सर्वोत्तम ज्ञान के लिए, जावा के लिए एकमात्र मॉकिंग टूल जिसमें एकाधिक इंटरफेस मॉक करने के लिए स्पष्ट समर्थन है JMockit है। (इस सुविधा को जोड़ने के लिए मेरी प्रेरणा Moq और राइनो Mocks, जो नेट उपकरण हैं से आया है।)

(mockit.ExpectationsUsingMockedTest JUnit 4 परीक्षण वर्ग से) एक उदाहरण:


@Test 
public <M extends Dependency & Runnable> void mockParameterWithTwoInterfaces(final M mock) 
{ 
    new Expectations() 
    { 
     { 
     mock.doSomething(true); returns(""); 
     mock.run(); 
     } 
    }; 

    assertEquals("", mock.doSomething(true)); 
    mock.run(); 
} 

Dependency और Runnable इंटरफेस है। doSomething विधि पहले से संबंधित है, और run दूसरे पर है।

+0

यह स्निपेट नकली वस्तु बनाने के लिए प्रतीत नहीं होता है। आप वह कैसे करेंगें ? –

+0

उपरोक्त परीक्षण मेरे लिए काम करता है। क्या आपने इसे चलाने की कोशिश की? –

49

हालांकि मैं मौलिक रूप से निक होल्ट के जवाब से सहमत हैं, मैंने सोचा कि मैं बाहर बिंदु चाहिए कि mockito क्या आप निम्नलिखित कॉल के साथ पूछना करने के लिए अनुमति देता है:

Foo mock = Mockito.mock(Foo.class, withSettings().extraInterfaces(Bar.class)); 

जाहिर है आप कलाकारों का उपयोग करना होगा: (Bar)mock

: ClassCastException

यहाँ जब आप एक Bar के रूप में नकली उपयोग करने की आवश्यकता है, लेकिन है कि कलाकारों फेंक नहीं होगा एक उदाहरण में थोड़ा और अधिक पूरा पूरी तरह से बेतुका है कि, यद्यपि है

2

इस समस्या को हल करने के लिए एक और तरीका है उपयोग करने के लिए है एक CGLib mixin:

final Interface1 interface1 = mockery.mock(Interface1.class); 
final Interface2 interface2 = mockery.mock(Interface2.class); 

service.setDependence(Mixin.create(new Object[]{ interface1, interface2 })); 

mockery.checking(new Expectations(){{ 
    oneOf(interface1).doSomething(); 
    oneOf(interface2).doNothing(); 
}}); 

service.execute(); 

या नहीं, यह एक अच्छा विचार है, यह चर्चा करने के लिए कुछ हो रहा है ...

संबंधित मुद्दे

 संबंधित मुद्दे