2012-03-15 16 views
23

PowerMock homepage पर उदाहरण से, मैं आंशिक रूप से Mockito के साथ एक निजी विधि मजाक के लिए निम्नलिखित उदाहरण देखें:क्या PowerMock में निजी स्थैतिक तरीकों के लिए आंशिक मॉकिंग का उपयोग करना संभव है?

@RunWith(PowerMockRunner.class) 
// We prepare PartialMockClass for test because it's final or we need to mock private or static methods 
@PrepareForTest(PartialMockClass.class) 
public class YourTestCase { 
@Test 
public void privatePartialMockingWithPowerMock() {   
    PartialMockClass classUnderTest = PowerMockito.spy(new PartialMockClass()); 

    // use PowerMockito to set up your expectation 
    PowerMockito.doReturn(value).when(classUnderTest, "methodToMock", "parameter1"); 

    // execute your test 
    classUnderTest.execute(); 

    // Use PowerMockito.verify() to verify result 
    PowerMockito.verifyPrivate(classUnderTest, times(2)).invoke("methodToMock", "parameter1"); 
} 

हालांकि, इस पद्धति काम करने के लिए जब निजी विधि हम नकली करना चाहते हैं स्थिर है प्रतीत नहीं होता। मैं नीचे दिए गए वर्ग के एक आंशिक नकली बनाना चाहते readfile विधि मज़ाक उड़ाया साथ:

package org.rich.powermockexample; 

import java.io.File; 
import java.io.IOException; 
import java.nio.charset.Charset; 
import java.util.List; 

import static com.google.common.io.Files.readLines; 

public class DataProvider { 

    public static List<String> getData() { 
     List<String> data = null; 
     try { 
      data = readFile(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return data; 
    } 

    private static List<String> readFile() throws IOException { 
     File file = new File("/some/path/to/file"); 
     List<String> lines = readLines(file, Charset.forName("utf-8")); 
     return lines; 
    } 

} 

कृपया कोई मुझे पता है कि यह कैसे प्राप्त किया जा सकता दे सकता है?

+0

क्यों, बिल्कुल? दूसरे शब्दों में, आप केवल GetData का मज़ाक उड़ाकर अनुकरण नहीं कर सकते हैं? –

+0

मैं कर सकता था - लेकिन मैं देखना चाहता था कि PowerMock के साथ आंशिक नकली में निजी स्थैतिक विधियों को संभालना संभव है या नहीं। –

+0

ओह। मुझे मैकेनिक्स देखना होगा, लेकिन AFAIK हां, बाइट-कोड मैनिपुलेशन के माध्यम से, वैसे ही, आप कन्स्ट्रक्टर को मजाक कर सकते हैं या कह सकते हैं। –

उत्तर

29

में थोड़ा और अधिक अनुसंधान करने के बाद, ऐसा लगता है कि PowerMockito.spy() और PowerMockito.doReturn() यहां क्या आवश्यक है:

package com.richashworth.powermockexample; 

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

import java.util.ArrayList; 
import java.util.List; 

import static org.junit.Assert.assertEquals; 


@RunWith(PowerMockRunner.class) 
@PrepareForTest({DataProvider.class}) 
public class ResultsWriterTest { 

    private static List<String> mockData = new ArrayList<String>(); 
    private ResultsWriter resultsWriter; 

    @BeforeClass 
    public static void setUpOnce() { 
     final String firstLine = "Line 1"; 
     final String secondLine = "Line 2"; 
     mockData.add(firstLine); 
     mockData.add(secondLine); 
    } 

    @Before 
    public void setUp() { 
     resultsWriter = new ResultsWriter(); 
    } 

    @Test 
    public void testGetDataAsString() throws Exception { 
     PowerMockito.spy(DataProvider.class); 
     PowerMockito.doReturn(mockData).when(DataProvider.class, "readFile"); 

     final String expectedData = "Line 1\nLine 2\n"; 
     final String returnedString = resultsWriter.getDataAsString(); 

     assertEquals(expectedData, returnedString); 
    } 

} 
+1

इस उदाहरण के लिए पूर्ण कोड सूची के लिए, मेरी ब्लॉग पोस्ट देखें [यहां] (http://richardashworth.blogspot.com/2012/03/turbocharge-your-mocking-framework-with.html) –

+4

1+: सुंदर जवाब, दोस्त। एक जादू की तरह काम करता है। PowerMock वेबसाइट ने यह भी वर्णन नहीं किया है जैसा आपने किया था। – acdcjunior

+2

अद्भुत! वास्तव में मुझे क्या चाहिए। धन्यवाद !! –

1

सामान्य रूप से, केवल आपके नियंत्रण से परे कक्षाओं के लिए स्थिर मॉकिंग का उपयोग करें (उदा। java.io.File)। चूंकि DataProvider और readFile आपके स्वयं के हैं, एक उचित वर्ग में रीफैक्टर DataProvider (यानी अपनी विधियों को गैर स्थैतिक बनाते हैं), readFile को एक सहायक ऑब्जेक्ट में खींचें और फिर उस पर नकल करें। यह उत्तर https://stackoverflow.com/a/8819339/116509 देखें।

+0

हाय, प्रतिक्रिया के लिए धन्यवाद। मैं मानता हूं कि यह उदाहरण थोड़ा सा संकुचित है, लेकिन मैंने यह पता लगाने के लिए एक साथ रखा कि PowerMock किसी विशेष समस्या को हल करने के बजाय सक्षम है। क्या आप कह रहे हैं कि यहां PowerMock का उपयोग करना संभव नहीं है? –

+0

मुझे नहीं पता लेकिन मेरे अनुभव में, यदि आप अपनी कक्षाओं पर निजी स्थैतिक तरीकों का मज़ाक उड़ा रहे हैं, तो आप शायद कुछ गलत कर रहे हैं। – artbristol

5

टेस्ट वर्ग:

@RunWith(PowerMockRunner.class) 
@PrepareForTest(DataProvider.class) 
public class DataProviderTest { 

    @Test 
    public void testGetDataWithMockedRead() throws Exception { 
     mockStaticPartial(DataProvider.class, "readFile"); 

     Method[] methods = MemberMatcher.methods(DataProvider.class, "readFile"); 
     expectPrivate(DataProvider.class, methods[0]).andReturn(Arrays.asList("ohai", "kthxbye")); 
     replay(DataProvider.class); 

     List<String> theData = DataProvider.getData(); 
     assertEquals("ohai", theData.get(0)); 
     assertEquals("kthxbye", theData.get(1)); 
    } 

} 

कक्षा परीक्षण किया जा रहा (मूल रूप से तुम्हारा):

public class DataProvider { 

    public static List<String> getData() { 
     try { 
      return readFile(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
      return null; 
     } 
    } 

    private static List<String> readFile() throws IOException { 
     File file = new File("/some/path/to/file"); 
     return readLines(file, Charset.forName("utf-8")); 
    } 

} 
+0

आह, धन्यवाद। ऐसा लगता है कि यह वही करता है जो मैं ढूंढ रहा हूं। मुझे एपीआई में मॉकस्टैटिक पार्टिकल विधि नहीं मिली - क्या आप इसके लिए पावरमॉक-मॉकिटो का उपयोग कर रहे थे, या यह आसानॉक शाखा में है? –

+1

चेंजलॉग से, मैं देखता हूं: "* हटाया गया मॉकस्टैटिक (कक्षा प्रकार, विधि विधि, विधि ... विधियां), मॉकस्टैटिक पार्टिकल, मॉकपार्टियल, मॉक (कक्षा प्रकार, विधि ... विधियां) और नकली (कक्षा प्रकार, विधि ... विधियों) Mockito एक्सटेंशन API से। आपको इसके बजाय PowerMockito.spy का उपयोग करना चाहिए। " चूंकि हम एक स्थैतिक विधि का नकल करने की कोशिश कर रहे हैं, मैं नहीं देख सकता कि यह कैसे किया जा सकता है यदि परीक्षा के तहत कक्षा का उदाहरण जासूस() विधि को दिया जाता है। –

+0

@RichAshworth EasyMock, लेकिन इससे कोई फर्क नहीं पड़ता। –