2011-01-12 25 views
19

Am का उपयोग कर प्राप्त करने और एक सुरक्षित विधि का एक अलग वर्ग में रहने वाले और भी अलग पैकेज आह्वान जावा प्रतिबिंब का उपयोग कर की कोशिश कर परीक्षण मामले में संरक्षित विधि को एक्सेस करना।जावा प्रतिबिंब

संरक्षित विधि युक्त वर्ग:

package com.myapp; 

public class MyServiceImpl { 

    protected List<String> retrieveItems(String status) { 
     // Implementation 
    } 
} 

कॉलिंग वर्ग:

java.lang.NoSuchMethodException: com.myapp.MyServiceImpl.retrieveItems() 

समय देने के लिए इस पढ़ने के लिए के लिए धन्यवाद:

package xxx.myapp.tests; 

import com.myapp.MyServiceImpl; 

public class MyTestCase { 

    List<String> items; 

    public void setUp() throws Exception { 

     MyServiceImpl service = new MyServiceImpl(); 
     Class clazz service.getClass(); 

     // Fails at the next line: 
     Method retrieveItems = clazz.getDeclaredMethod("retrieveItems"); 

     // How to invoke the method and return List<String> items? 
     // tried this but it fails? 
     retrieveItems.invoke(clazz, "S"); 
    } 
} 

संकलक इस अपवाद फेंकता है।

उत्तर

23

अपने कोड के साथ समस्या यह है कि getDeclaredMethod समारोह दोनों नाम से और तर्क प्रकार से एक समारोह को खोजता है। कॉल

Method retrieveItems = clazz.getDeclaredMethod("retrieveItems"); 

के साथ कोड कोई तर्क के साथ एक विधि retrieveItems() के लिए दिखेगा। विधि आप देख रहे हैं एक तर्क, एक स्ट्रिंग ले करता है, ताकि आप

Method retrieveItems = clazz.getDeclaredMethod("retrieveItems", String.class); 

यह बुलाना चाहिए retrieveItems(String) के लिए खोज करने के लिए है, जो आप जो खोज रहे हैं जावा बता देंगे।

+0

+1 - इस समस्या को अपवाद नहीं है कि है फ़्लैग करने का। एक बार विधि को पुनर्प्राप्त करने के बाद, इसे @ जेके के उत्तर के अनुसार सुलभ किया जाना चाहिए। –

6

इसके बजाय कि मुश्किल प्रतिबिंब सामान का उपयोग करने का, क्यों बस एक व्युत्पन्न वर्ग है, जो संरक्षित विधि के लिए उपयोग होगा नहीं बना?

आगे विचार के लिए Is it bad practice to use Reflection in Unit testing? देखें।

+0

+1 - यह एक और समझदार दृष्टिकोण है, आईएमओ। –

+1

-1 - यह रूट प्रश्न का उत्तर नहीं देता है। जावा में प्रतिबिंब के माध्यम से आप संरक्षित विधि का उपयोग कैसे करते हैं? – BrainSlugs83

+0

@ BrainSlugs83 प्रश्न का शीर्षक दोबारा पढ़ें।ओपी वास्तव में कुछ कोड का परीक्षण करना चाहता है, लेकिन गलत तरीके से सोचता है कि उन्हें प्रतिबिंब का उपयोग करने की आवश्यकता है। उनके पास एक एक्सवाई समस्या है। मेरा जवाब उनकी असली समस्या से बात करता है, न कि उनके प्रस्तावित समाधान। – Raedwald

2

आप एक ही पैकेज में अपने testcases डाल दिया (com.myappcom.myapp.tests के बजाय) वे संरक्षित (और डिफ़ॉल्ट पैकेज स्तर) के सदस्यों के लिए उपयोग होगा।

तो फिर तुम service.retrieveMembers(status) सीधे कॉल कर सकते हैं।

यदि आप परीक्षण से स्रोत को अलग करने की कोशिश कर रहे हैं, तो आमतौर पर एक अलग स्रोत निर्देशिका का उपयोग करना बेहतर होता है (उदाहरण के लिए src निर्देशिका और test निर्देशिका)।

+0

यदि परीक्षण एक ही पैकेज में हैं तो आप अपनी संकलित कक्षा फ़ाइलों को एक ही लक्ष्य निर्देशिका में होने की संभावना है, जो किसी भी तैनाती फ़ाइल को टेस्ट क्लास फाइलों के समूह के साथ फहराएगा जबतक कि आपके पास हर पैकेज/प्रोजेक्ट नहीं है और लक्ष्य निर्देशिका के लिए बहिष्करण नियम परिभाषित करें। मेरी राय में एक अच्छा विचार नहीं है। –

+0

यही कारण है कि आप अपने परीक्षणों के लिए एक अलग स्रोत निर्देशिका का उपयोग करते हैं। मैवेन काम जैसे मानक तरीके उपकरण हैं। – Nick

+0

हाँ, मैंने आपकी पोस्ट को गलत समझा। मैं देख रहा हूँ कि अब आप क्या कह रहे हैं, धन्यवाद! –

2

कोई प्रतिबिंब या विरासत की जरूरत है:

, अपने MyTestCaseके तहत पैकेजcom.myapp रखो 'सुरक्षित' गुंजाइश के रूप में भी 'पैकेज' है। फिर MyTestCaseMyServiceImpl के संरक्षित तरीकों तक पहुंच सकते हैं।

+0

यदि परीक्षण एक ही पैकेज में हैं तो आप अपनी संकलित कक्षा फ़ाइलों को एक ही लक्ष्य निर्देशिका में होने की संभावना है, जो किसी भी तैनाती फ़ाइल को टेस्ट क्लास फाइलों के समूह के साथ फहराएगा जबतक कि आपके पास हर पैकेज/प्रोजेक्ट नहीं है और लक्ष्य निर्देशिका के लिए बहिष्करण नियम परिभाषित करें। मेरी राय में एक अच्छा विचार नहीं है। –

+0

@ सैंडीसिमोंटन, इसे हासिल किया जा सकता है। हम अपनी परियोजना संरचना को निम्नानुसार बना सकते हैं (maven): 'src-> मुख्य-> जावा 'में सभी कोड शामिल हैं। 'src-> test-> जावा 'में सभी परीक्षण शामिल हैं। –

2

तुम आह्वान विधि में वर्ग के लिए लिंक के बजाय निर्मित ऑब्जेक्ट के लिए लिंक का उपयोग करें और अनलॉक पहुंच के लिए उपयोग Method.setAccessible (सही) मंगलाचरण के लिए कार्य करना चाहिए:

public void setUp() throws Exception { 
    MyServiceImpl service = new MyServiceImpl(); 
    Class<?> clazz = service.getClass(); 
    Method retrieveItems = clazz.getDeclaredMethod("retrieveItems", String.class); 
    retrieveItems.setAccessible(true); 
    items = (List<String>)retrieveItems.invoke(service, "S"); 
} 
संबंधित मुद्दे