2012-11-13 19 views
55

साथ मॉक एक निर्माता मैं नीचे के रूप में एक वर्ग है। मुझे कोई कॉल चाहिए: new A($$$any string$$$).check() एक डमी स्ट्रिंग "test" देता है।पैरामीटर

मैंने कोशिश की:

A a = mock(A.class); 
when(a.check()).thenReturn("test"); 

String test = a.check(); // to this point, everything works. test shows as "tests" 

whenNew(A.class).withArguments(Matchers.anyString()).thenReturn(rk); 
// also tried: 
//whenNew(A.class).withParameterTypes(String.class).withArguments(Matchers.anyString()).thenReturn(rk); 

new A("random string").check(); // this doesn't work 

लेकिन यह काम करने लगता है। new A($$$any string$$$).check() अभी भी A की मॉक ऑब्जेक्ट लाने के बजाय कन्स्ट्रक्टर तर्क के माध्यम से जा रहा है।

+0

अपने मज़ाक उड़ाया जांच() विधि सही काम कर रहा है एक ही रहता है? –

+0

@BenGlasser चेक() ठीक काम करता है। बस जब नया काम नहीं कर रहा है। मैंने विवरण भी अपडेट किया। – Shengjie

उत्तर

56

कोड आप Mockito और Powermockito के नवीनतम संस्करण के साथ मेरे लिए काम करता है पोस्ट। शायद आपने ए तैयार नहीं किया है? इस प्रयास करें:

A.java

public class A { 
    private final String test; 

    public A(String test) { 
     this.test = test; 
    } 

    public String check() { 
     return "checked " + this.test; 
    } 
} 

MockA.java

import static org.hamcrest.MatcherAssert.assertThat; 
import static org.hamcrest.Matchers.equalTo; 
import static org.mockito.Mockito.mock; 
import static org.mockito.Mockito.when; 

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.Mockito; 
import org.powermock.api.mockito.PowerMockito; 
import org.powermock.core.classloader.annotations.PrepareForTest; 
import org.powermock.modules.junit4.PowerMockRunner; 

@RunWith(PowerMockRunner.class) 
@PrepareForTest(A.class) 
public class MockA { 
    @Test 
    public void test_not_mocked() throws Throwable { 
     assertThat(new A("random string").check(), equalTo("checked random string")); 
    } 
    @Test 
    public void test_mocked() throws Throwable { 
     A a = mock(A.class); 
     when(a.check()).thenReturn("test"); 
     PowerMockito.whenNew(A.class).withArguments(Mockito.anyString()).thenReturn(a); 
     assertThat(new A("random string").check(), equalTo("test")); 
    } 
} 

दोनों परीक्षण mockito 1.9.0, powermockito 1.4.12 और JUnit 4.8.2

+13

यह भी ध्यान दें कि यदि निर्माता को किसी अन्य वर्ग से बुलाया जाता है, तो इसे 'PrepareForTest' में सूची में शामिल करें –

33

मेरे ज्ञान के लिए, आप मॉकिटो, केवल विधियों के साथ रचनाकारों का नकल नहीं कर सकते हैं। लेकिन मॉकिटो Google कोड पेज पर विकी के अनुसार आपके वर्ग में एक विधि बनाकर कन्स्ट्रक्टर व्यवहार का नकल करने का एक तरीका है जो उस वर्ग का एक नया उदाहरण लौटाता है। तो आप उस विधि को नकल कर सकते हैं। नीचे है एक excerpt directly from the Mockito wiki:

पैटर्न 1 - का उपयोग कर ऑब्जेक्ट निर्माण के लिए एक लाइन तरीकों

पैटर्न 1 (एक वर्ग MyClass बुलाया परीक्षण) का उपयोग करने के लिए आपको

Foo foo = new Foo(a, b, c); 
की तरह एक फोन की जगह लेंगे

Foo foo = makeFoo(a, b, c); 

साथ

और एक पंक्ति metho बारे में डी

Foo makeFoo(A a, B b, C c) { 
     return new Foo(a, b, c); 
    } 

यह महत्वपूर्ण है कि आप विधि में कोई तर्क शामिल न करें; सिर्फ एक पंक्ति जो ऑब्जेक्ट बनाता है। इसका कारण यह है कि इकाई परीक्षण के लिए विधि कभी भी नहीं जा रही है।

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

आपका परीक्षण वर्ग की तरह

@Mock private Foo mockFoo; 
    private MyClass toTest = spy(new MyClass()); 

अंत में, अपने परीक्षा पद्धति के अंदर तुम बाहर makeFoo करने के लिए कॉल की तरह

doReturn(mockFoo) 
     .when(toTest) 
     .makeFoo(any(A.class), any(B.class), any(C.class)); 

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

यदि आप बस अपनी कक्षा के एक मजाकिया वस्तु को वापस करना चाहते हैं तो मुझे लगता है कि यह आपके लिए काम करना चाहिए।किसी भी मामले में आप यहाँ ऑब्जेक्ट निर्माण मजाक के बारे में अधिक पढ़ सकते हैं:

http://code.google.com/p/mockito/wiki/MockingObjectCreation

+10

+1, मुझे यह तथ्य पसंद नहीं है कि मुझे अपने स्रोत कोड को समायोजित करने की आवश्यकता है और इसे अधिक मॉकिटो अनुकूल बनाएं। साझा करने के लिए धन्यवाद। – Shengjie

+15

स्रोत कोड होना कभी भी बुरा नहीं है जो अधिक टेस्टेबल है, या जब आप अपना कोड लिखते हैं तो टेस्टेबिलिटी एंटी-पैटर्न से बचने के लिए। यदि आप स्रोत लिखते हैं जो अधिक टेस्टेबल है, तो यह स्वचालित रूप से अधिक रखरखाव योग्य होता है। अपने कन्स्ट्रक्टर कॉल को अपने तरीके से अलग करना इसे हासिल करने का एक तरीका है। –

8
साथ पास करना चाहिए

पावरमॉक का उपयोग किए बिना .... बेन ग्लासर उत्तर के आधार पर नीचे दिया गया उदाहरण देखें क्योंकि मुझे इसे समझने में कुछ समय लगा .. होप जो कुछ समय बचाता है ...

मूल वर्ग:

public class AClazz { 

    public void updateObject(CClazz cClazzObj) { 
     log.debug("Bundler set."); 
     cClazzObj.setBundler(new BClazz(cClazzObj, 10)); 
    } 
} 

संशोधित वर्ग:

@Slf4j 
public class AClazz { 

    public void updateObject(CClazz cClazzObj) { 
     log.debug("Bundler set."); 
     cClazzObj.setBundler(getBObject(cClazzObj, 10)); 
    } 

    protected BClazz getBObject(CClazz cClazzObj, int i) { 
     return new BClazz(cClazzObj, 10); 
    } 
} 

टेस्ट कक्षा

public class AClazzTest { 

    @InjectMocks 
    @Spy 
    private AClazz aClazzObj; 

    @Mock 
    private CClazz cClazzObj; 

    @Mock 
    private BClazz bClassObj; 

    @Before 
    public void setUp() throws Exception { 
     Mockito.doReturn(bClassObj) 
       .when(aClazzObj) 
       .getBObject(Mockito.eq(cClazzObj), Mockito.anyInt()); 
    } 

    @Test 
    public void testConfigStrategy() { 
     aClazzObj.updateObject(cClazzObj); 

     Mockito.verify(cClazzObj, Mockito.times(1)).setBundler(bClassObj); 
    } 
} 
1

Mockito सीमाओं अंतिम परीक्षण है, स्टेशन टिक, और निजी तरीकों।

एक java.io.File वर्ग की नकली निर्माता:

new MockUp<File>(){ 
    @Mock 
    public void $init(String pathname){ 
     System.out.println(pathname); 
     // or do whatever you want 
    } 
}; 
  • सार्वजनिक निर्माता

    JMockit परीक्षण पुस्तकालय के साथ

    , तो आप बहुत ही आसान और सरल रूप में नीचे कुछ सामान कर सकते हैं नाम $ init

  • तर्कों और अपवादों के साथ प्रतिस्थापित किया जाना चाहिए
  • वापसी प्रकार को शून्य
  • के रूप में परिभाषित किया जाना चाहिए

मॉक एक स्थिर विधि:

  • विधि नकली हस्ताक्षर
  • विधि हस्ताक्षर से स्थिर हटाने अन्यथा