2014-12-27 2 views
16

मैं mockito का एक बड़ा प्रशंसक हूँ, one of my projects जो जावा 8 का उपयोग करता है के लिए दुर्भाग्य से, यह मुझ पर विफल रहता है ...क्या आप इंटरफ़ेस में डिफ़ॉल्ट विधियों के साथ मॉकिटो (1.10.17) काम कर सकते हैं?

परिदृश्य: foo.bar() रिटर्न

public final class MockTest 
{ 
    @Test 
    public void testDefaultMethodsWithMocks() 
    { 
     final Foo foo = mock(Foo.class); 

     //when(foo.bar()).thenCallRealMethod(); 

     assertThat(foo.bar()).isEqualTo(42); 
    } 

    @FunctionalInterface 
    private interface Foo 
    { 
     int foo(); 

     default int bar() 
     { 
      return 42; 
     } 
    } 
} 

दुर्भाग्य से, परीक्षण विफल रहता है और 0.

जब मैं when() लाइन uncomment, मैं एक स्टैक ट्रेस मिलता है ...

java.lang.NoSuchMethodError: java.lang.Object.bar()I 
    at com.github.fge.lambdas.MockTest.testDefaultMethodsWithMocks(MockTest.java:18) 

यह मैवेन पर उपलब्ध नवीनतम स्थिर संस्करण है; चारों ओर गुगल करने से मुझे जावा 8 में इस नई कार्यक्षमता के संबंध में मॉकिटो की स्थिति के बारे में बहुत कुछ नहीं बताया गया था ...

क्या आप इसे इंटरफेस और spy() पर लागू करने के अलावा किसी अन्य तरीके से काम कर सकते हैं (यह काम करता है)?

+0

मुझे लगता है कि इस तरह से है कि Mockito mocks के लिए गतिशील प्रॉक्सी पीढ़ी संभालती है और बुनियादी सुविधाओं के लिए एक अद्यतन की आवश्यकता होगी का प्रभाव है। क्या आपने जांच की है कि इसके लिए मॉकिटो के खिलाफ कोई बकाया मुद्दा है या नहीं? – chrylis

+0

@chrylis no, विशेष रूप से इस बिंदु के लिए नहीं; जावा 8 और डिफॉल्ट विधियों से संबंधित एक मुद्दा खोला गया है, और इश्यु ओपनर ने सही तरीके से बताया (मैं बेवकूफ हूं कि पहले इस बारे में सोचा नहीं था) कि उसे परीक्षण कार्य करने के लिए जावा 8 के साथ मॉकिटो संकलित करना पड़ा। उदास लग रहा है:/ – fge

+0

हाँ। वहाँ अभी भी कुछ पुस्तकालय हैं जो 1.4 के लिए कांटे बनाए रखते हैं। – chrylis

उत्तर

10

मॉकिटो 2.x, जेडीके 8 डिफ़ॉल्ट विधियां समर्थित समर्थित हैं।

mockito 1.x के साथ

यह संभव नहीं,


दुर्भाग्य से अभी भी संभव नहीं (mockito 1.10.19) GitHub पर है, README.md से है पुराना जवाब 'पृष्ठ

जेडीके 8 स्थिति

यदि आप डिफ़ॉल्ट विधियों (उर्फ डिफेंडर विधियों) से दूर रहते हैं तो Mockito JDK8 के साथ ठीक काम करना चाहिए। लैम्ब्डा उपयोग उत्तर के लिए उतना ही अच्छा काम कर सकता है। हम फिलहाल हर जेडीके 8 फीचर्स के बारे में अनिश्चित हैं, जैसे लैम्बडा का उपयोग करने वाले नकली को क्रमबद्ध करना। त्रुटि रिपोर्ट और पुल अनुरोध स्वागत है हालांकि (योगदान गाइड)।

संपादित करें 1: रक्षक तरीकों और डिफ़ॉल्ट तरीकों एक ही बात के लिए अलग अलग नाम हैं।

मैं एक mockmaker प्रतिस्थापन कि के रूप में कुछ opcodes जावा में एक अलग अर्थ है इस तरह के मामलों के लिए 8 opcodes ठीक से जावा संभाल लेंगे के लिए आशा 8.

संपादित 2: mockito रीडमी अपडेट किया गया, और उसके अनुसार इस उद्धरण

+0

उह, हाँ, मैंने इसे देखा, लेकिन मुझे आश्चर्य है कि "डिफेंडर विधियों" वास्तव में इंटरफेस में डिफ़ॉल्ट तरीकों का मतलब है; और फिर भी "डिफेंडर विधि" क्या है? – fge

+2

हाँ यह _default विधियों_ – Brice

+1

के लिए बस एक और नाम है ठीक है, ठीक है, तो मुझे लगता है कि मैं रीडमे अपडेट करने के लिए एक पुल अनुरोध सबमिट करूंगा ... मुझे विश्वास नहीं है कि बहुत से लोग जानते हैं कि वे दो समानार्थी हैं – fge

3

मैंने अभी मॉकिटो 2.0.38-बीटा की कोशिश की, और यह पहले से ही उस संस्करण में काम करता है। लेकिन मॉकिटो को स्पष्ट रूप से डिफ़ॉल्ट कार्यान्वयन को कॉल करने के लिए कहा जाना चाहिए।

Foo foo = mock(Foo.class); 
assertThat(foo.bar()).isEqualTo(0); 

when(foo.bar()).thenCallRealMethod(); 
assertThat(foo.bar()).isEqualTo(42); 
1

आप इंटरफ़ेस को कार्यान्वित करके इस सीमा के आसपास हो सकते हैं (मॉकिटो 1.10 में परीक्षण किया गया।19):

public class TestClass { 
    @Mock ImplementsIntWithDefaultMethods someObject; 


    @Test public void test() throws Exception { 
    // calling default method on mocked subtype works 
    someObject.callDefaultMethod(); 
    } 


    /* Type that implements the interface */ 
    static class ImplementsIntWithDefaultMethods implements IntWithDefaultMethod { } 

    /* Interface you need mocked */ 
    interface IntWithDefaultMethod { 
    default void callDefaultMethod { } 
    } 
} 
0

मैं सिर्फ Mockito (org.mockito के साथ एक ही मुद्दा में भाग: mockito कोर: 1.10.19)। समस्या यह है: मैं org.springframework.boot पर निर्भरताओं की वजह से मॉकिटो संस्करण (2.7.22 काम करेगा) को बदलने में सक्षम नहीं हूं: वसंत-बूट-स्टार्टर-टेस्ट: 1.4.3.RELEASE जिसे हम उपयोग कर रहे हैं (Spring, Mockito issue) ।

मुझे मिला सबसे आसान समाधान है मेरी टेस्ट क्लास के भीतर एक निजी अमूर्त वर्ग के साथ इंटरफेस को कार्यान्वित करना और उस पर मजाक करना (@ मिहाई बोजिन के समाधान की तुलना में)। ऐसा करने से आपको इंटरफ़ेस द्वारा आवश्यक सभी विधियों को "कार्यान्वित" करने के लिए परेशानी से दूर रखा जाता है।

मेगावाट:

public interface InterfaceWithDefaults implements SomeOtherInterface { 
    default int someConstantWithoutSense() { 
     return 11; 
    } 
} 

public class SomeTest { 
    private abstract class Dummy implements InterfaceWithDefaults {} 

    @Test 
    public void testConstant() { 
     InterfaceWithDefaults iwd = Mockito.mock(Dummy.class); 

     Assert.assertEquals(11, iwd.someConstantWithoutSense()); 
    } 
} 
संबंधित मुद्दे

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