2016-02-19 11 views
5

का उपयोग कर URL वर्ग का नकल करने में असमर्थ मैं अपने कोड में java.net.URL क्लास के निर्माण को नकल करने के लिए PowerMockito का उपयोग करने का प्रयास कर रहा हूं। असल में, मैं वास्तविक HTTP अनुरोध को होने से रोकना चाहता हूं और इसके बजाय 1) अनुरोध किए जाने पर डेटा की जांच करें और 2) एक मजाकिया प्रतिक्रिया पर अपना खुद का परीक्षण डेटा वापस आपूर्ति करें।PowerMockito/Mockito

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ URL.class, MockedHttpConnection.class }) 
public class Test { 
    URL mockedURL = PowerMockito.mock(URL.class); 
    MockedHttpConnection mockedConnection = PowerMockito.mock(MockedHttpConnection.class); 

... 
    PowerMockito.whenNew(URL.class).withParameterTypes(String.class).withArguments("MyURLString").thenReturn(mockedURL); 
PowerMockito.when(mockedURL.openConnection()).thenReturn(mockedConnection); 

... 
} 

कोड मैं इस तरह दिखता है परीक्षण करना चाहते हैं:

URL wlInvokeUrl = new URL(wlInvokeUrlString); 
connection = (HttpURLConnection) wlInvokeUrl.openConnection(); 

अपने परीक्षण परिदृश्य में इससे पहले मैं नकली wlInvokeUrlString "MyURLString" मैच के लिए यह है कि मैं क्या कोशिश कर रहा हूँ है। मैंने नकली इंजेक्ट करने की कोशिश करते समय, नई लाइन के विभिन्न अन्य रूपों का उपयोग करने का भी प्रयास किया है। कोई फर्क नहीं पड़ता कि मैं क्या कोशिश करता हूं, यह कभी भी कन्स्ट्रक्टर को हस्तक्षेप नहीं करता है। मैं बस इतना करना चाहता हूं कि खोलने के लिए कॉल को पकड़ें() और इसे वास्तविक के बजाय मेरा मॉक किया गया HTTP कनेक्शन वापस कर दें।

मैंने एक ही स्क्रिप्ट में इस से आगे के अन्य वर्गों का मज़ाक उड़ाया है और ये उम्मीद के अनुसार काम कर रहे हैं। या तो मुझे आंखों की दूसरी जोड़ी (शायद सच) की आवश्यकता है या यूआरएल वर्ग के बारे में कुछ अद्वितीय है। मैंने नोटिस किया कि अगर मैं "जब नया (URL.class) .withAnyArguments()" का उपयोग करता हूं और "फिर वापसी" को "फिर Answers" में बदलता हूं तो मैं इसे ट्रिगर करने के लिए प्राप्त कर सकता हूं। केवल समस्या यह है कि मुझे अपने कोड के लिए यूआरएल कॉल कभी नहीं मिला। जो मैं देखता हूं वह पैरामीटर के लिए सभी नल के साथ URL.class के लिए 3-तर्क कन्स्ट्रक्टर का आविष्कार है। क्या यह कक्षा जावा रनटाइम से हो सकती है और परीक्षण धावक द्वारा बूटस्ट्रैप किया जा सकता है? किसी भी प्रकार की मदद की बेहद सराहना की जाती है।

+0

आपको इसका परीक्षण करने के लिए Powermock की आवश्यकता नहीं है। फ़ाइल आधारित पथ ("फ़ाइल: //my-test.properties") का उपयोग करने के उदाहरण के लिए बस स्ट्रिंग यूआरएल का मज़ाक उड़ाएं। यह काम करेगा, और आप जिस डेटा को चाहते हैं उसे पास कर सकते हैं –

+0

@ जेरेमीबी क्या आप इसे थोड़ा और विस्तारित कर सकते हैं? यह एक सुरुचिपूर्ण और सरल समाधान की तरह लगता है, लेकिन परीक्षण के तहत कोड एक HttpURLConnection की अपेक्षा कर रहा है और मुझे क्लासकास्ट अपवाद प्राप्त होता है यदि मैं किसी फ़ाइल को संदर्भित करने के लिए URL स्ट्रिंग को बदलता हूं (यानी java.lang.ClassCastException: sun.net.www.protocol। ftp.FtpURL कनेक्शन को java.net पर नहीं डाला जा सकता है। HttpURLConnection)। साथ ही, आप इस दृष्टिकोण का उपयोग कर अनुरोध पर इनपुट पैरामीटर कैसे सत्यापित करेंगे? – Jim

+0

आपको सीधे 'HttpURLConnection', लेकिन 'URL' और' URLConnection' का उपयोग नहीं करना चाहिए। 'HttpURLConnection' में उपयोगी कुछ भी नहीं है। परिवहन परत को सारणी देने के लिए यह एक यूआरएल का उद्देश्य है। –

उत्तर

0

मुझे यकीन नहीं है कि .withParameterTypes(x) और .withArguments(x) के बीच का अंतर है, लेकिन मुझे विश्वास है कि आपको अपने कोड के काम के लिए निम्नानुसार सेट अप करने की आवश्यकता है। इसे आज़माएं और मुझे बताएं कि इससे मदद नहीं मिलती है।

PowerMockito.when(mockedURL.openConnection()).thenReturn(mockedConnection); 
PowerMockito.whenNew(URL.class).withArguments(Mockito.anyString()).thenReturn(mockedURL); 
+0

मैंने इन पंक्तियों की कोशिश की, लेकिन मैं वही परिणाम देख रहा हूं। मॉक किए गए ऑब्जेक्ट्स का उपयोग करने के बजाय असली यूआरएल और HttpURLConnection कक्षाएं बनाई और उपयोग की जाती हैं। क्या समस्या इस तथ्य के साथ हो सकती है कि यूआरएल वर्ग को अंतिम घोषित किया गया है? मैंने जो पढ़ा है उससे PowerMockito इसे संभालने में सक्षम होना चाहिए। – Jim

0

समस्या यह है कि वास्तविक कॉल के तर्क आपके नकली में अपेक्षित से मेल नहीं खाते हैं।

PowerMockito.whenNew(URL.class).withParameterTypes(String.class).withArguments("MyURLString").thenReturn(mockedURL)mockedURL वापस लौटाएगा केवल कॉल new URL("MyURLString") है।

आप के लिए इसे बदल हैं:

PowerMockito.whenNew(URL.class).withParameterTypes(String.class) 
    .withArguments(org.mockito.Matchers.any(String.class)).thenReturn(mockedURL); 

यह किसी भी स्ट्रिंग निर्माता URL(String) (यहां तक ​​कि null) के लिए पारित पकड़ने और अपने नकली वापस आ जाएगी।


आप

"whenNew (URL.class) .withAnyArguments()" की कोशिश की और करने के लिए "thenReturn" "thenAnswer" मैं इसे गति प्रदान करने के मिल सकता है परिवर्तित करते हैं। केवल समस्या यह है कि मुझे अपने कोड के लिए यूआरएल कॉल कभी नहीं मिलता है। मैं जो देखता हूं वह 312 तर्कपैरामीटर के लिए सभी नल के साथ URL.class के लिए 3-तर्क कन्स्ट्रक्टर का आविष्कार है।

PowerMock सभी कंस्ट्रक्टर्स (org.powermock.api.mockito.internal.expectation.DelegatingToConstructorsOngoingStubbing.InvokeStubMethod लाइन 122 पर) उपहास करने के लिए तो यह पहले एक (3 तर्क के साथ) कहता है और उसके जवाब नकली कोशिश करेंगे। लेकिन बाद की कॉल पहले से ही मजाक कर देगी क्योंकि आपने इसे के लिए किसी भी तर्क के लिए नकली करने के लिए कहा था। यही कारण है कि आप अपने Answer में null, null, null के साथ केवल एक कॉल देखते हैं।

+0

मैंने इस काम को करने की कोशिश करने के दौरान कई चीजों की कोशिश की है, जिसमें आपके सुझाव पर भिन्नता शामिल है। जब आप उल्लेख करते हैं तो नई लाइन को बदलकर मैंने पुनः प्रयास किया, लेकिन फिर भी वही परिणाम मिलते हैं। कोई अन्य विचार? – Jim

0

PowerMockito.whenNew का उपयोग करते समय यह एक आम गलती है।

ध्यान दें कि आपको क्लास को परीक्षण के लिए MyClass का नया उदाहरण बनाने के लिए तैयार करना होगा, न कि MyClass स्वयं। जैसे यदि वर्ग नई MyClass कर() कहा जाता है एक्स तो आप क्रम में @PrepareForTest (X.class) करने के लिए whenNew

काम करने के लिए Powermock wiki

तो से होगा, आप थोड़ा परिवर्तन की जरूरत है आपके परीक्षण और @PrepareForTest करने के लिए एक वर्ग है जो URL का एक नया उदाहरण बनाने जोड़ना जैसे:

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ URL.class, MockedHttpConnection.class , ConnectionUser.class}) 
public class URLTest { 
public class URLTest { 

    private ConnectionUser connectionUser; 

    @Before 
    public void setUp() throws Exception { 

     connectionUser = new ConnectionUser(); 
    } 

    @Test 
    public void testName() throws Exception { 

     URL mockedURL = PowerMockito.mock(URL.class); 
     MockedHttpConnection mockedConnection = PowerMockito.mock(MockedHttpConnection.class); 

     PowerMockito.whenNew(URL.class).withParameterTypes(String.class).withArguments("MyURLString").thenReturn(mockedURL); 
     PowerMockito.when(mockedURL.openConnection()).thenReturn(mockedConnection); 

     connectionUser.open(); 

     assertEquals(mockedConnection, connectionUser.getConnection()); 


    } 
} 

जहां:

public class ConnectionUser { 

    private String wlInvokeUrlString = "MyURLString"; 
    private HttpURLConnection connection; 

    public void open() throws IOException { 
     URL wlInvokeUrl = new URL(wlInvokeUrlString); 
     connection = (HttpURLConnection) wlInvokeUrl.openConnection(); 
    } 

    public HttpURLConnection getConnection() { 
     return connection; 
    } 
} 
+0

आपका उत्तर काम करने के सबसे नज़दीकी आता है। इन परिवर्तनों को करने के बाद नकली यूआरएल कन्स्ट्रक्टर का आह्वान किया जा रहा है। हालांकि, यह हमेशा एक शून्य वस्तु वापस कर रहा है। इसके द्वारा, मेरा मतलब है कि लाइन 'यूआरएल wlInvokeUrl = नया यूआरएल (wlInvokeUrlString); 'हमेशा wlInvokeUrl को शून्य करने के लिए असाइन करता है। मैंने अपने कोड को दोबारा प्रतिक्रिया देकर मूल समस्या के आसपास काम किया है, लेकिन यदि आपके पास कोई अन्य सुझाव है तो मैं इसके लिए PowerMockito काम देखने के लिए अभी भी प्रतिबद्ध हूं। – Jim

+0

क्या आप PowerMock, Mockito, Java के संस्करणों का उपयोग करते हैं? मैंने नवीनतम रिलीज और मॉकिटो 1.10.1 9 के साथ परीक्षण किया है और अगर मैं 'mockedUrl'via' null' को प्रतिस्थापित करता हूं तो केवल अपनी समस्या को पुन: पेश कर सकता हूं। इस तरह: 'PowerMockito.whenNew (URL.class) .withArguments ("MyURLString")। फिर वापसी (शून्य);' अन्य सभी मामलों में परीक्षण का मेरा संस्करण पास हो गया है। वैसे, मैं परीक्षण चलाने के लिए जावा 8 का उपयोग करता हूं। –

+0

क्या आप अपने पर्यावरण को अपने पर्यावरण में चलाने की कोशिश कर सकते हैं? –

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

  • कोई संबंधित समस्या नहीं^_^