2011-08-16 19 views
7

निजी तरीकों के परीक्षण की सार्थकता पर भिन्न राय हैं, उदाहरण के लिए, here और here। मैं व्यक्तिगत रूप से सोचता हूं कि यह समझ में आता है, सवाल यह है कि इसे ठीक से कैसे किया जाए। सी ++ आप एक #define hack का उपयोग करें या परीक्षण वर्ग friend कर सकते हैं, वहाँ InternalsVisibleToAttribute में सी # में, लेकिन जावा में हम या तो reflection उपयोग करने के लिए या और annotate them as such उन्हें "परीक्षण के लिए दिखाई दे" बनाने के लिए क्रम में आशय स्पष्ट करना है। दोनों के नुकसान काफी स्पष्ट होना चाहिए।जावा उपकरण?

मुझे लगता है कि कुछ बेहतर होना चाहिए।

public class Something { 
    private int internalSecret() { 
     return 43; 
    } 
} 

के साथ शुरू यह अच्छा होगा की तरह

@MakeVisibleForTesting Something something = new Something(); 
Assert.assertEquals(43, something.internalSecret()); 

यहाँ परीक्षण कोड में निजी तरीकों कॉल करने के लिए एनोटेशन चुपचाप प्रतिबिंब का उपयोग something के निजी तरीकों के लिए सभी कॉल में बदल सकते हैं सक्षम होने के लिए। मुझे आश्चर्य है कि Lombok ऐसा कर सकता है (और लेखकों से पूछेगा)।

यह काफी संभव है कि इतना जादू करना बहुत जटिल साबित होता है, और किसी भी मामले में इसमें कुछ समय लगेगा, इसलिए मैं कुछ विकल्प ढूंढ रहा हूं। हो सकता है कि @Decapsulate की तरह कुछ के साथ परीक्षण के अंतर्गत कक्षा व्याख्या और एक वर्ग Decapsulated_Something उत्पन्न करने के लिए

public class Decapsulated_Something { 
    public Decapsulated_Something(Something delegate) { 
     this.delegate = delegate 
    } 
    public boolean internalSecret() { 
     // call "delegate.internalSecret()" using reflection 
    } 
    ... 
} 

जो

Decapsulated_Something something = new Decapsulated_Something(new Something()); 
Assert.assertEquals(43, something.internalSecret()); 

का उपयोग करने की अनुमति होगी की तरह लग रही एक एनोटेशन प्रोसेसर का उपयोग मैं टिप्पणी के साथ ज्यादा अनुभव नहीं है प्रसंस्करण, इसलिए मैं यहां पहले पूछता हूं:

  • इसे लागू करने के लिए कितना जटिल है?
  • मुझे क्या भूल गया?
  • सामान्य रूप से आप इसके बारे में क्या सोचते हैं?
+0

क्या आप एक उपकरण पूछ रहे हैं, या खुद को कैसे लिखना है? – Raedwald

+0

@ रेडवाल्ड मैं पूछ रहा हूं कि इसे कैसे हल किया जाए। खुद को विंग करना एक विकल्प है, लेकिन पहिया को फिर से शुरू करना स्पष्ट रूप से वांछित नहीं है। पैकेज निजी के लिए – maaartinus

उत्तर

1

ऐसा

@MakeVisibleForTesting Something something = new Something(); 
Assert.assertEquals(43, something.internalSecret()); 

वहाँ एक विधि टिप्पणी के रूप में इस तरह के बात है परीक्षण कोड में निजी तरीकों कॉल करने के लिए सक्षम होने के लिए अच्छा होगा, बाहर की जाँच dp4j के @TestPrivates:

@Test 
@TestPrivates 
//since the method is annotated with JUnit's @Test this annotation is redundant. 
// You just need to have dp4j on the classpath. 
    public void somethingTest(){ 
     Something something = new Something(); 
     int sthSecret = something.internalSecret(); 
     Assert.assertEquals(43, sthSecret); //cannot use something.internalSecret() directly because of bug [dp4j-13][2] 
    } 
7

ऐसा कार्यान्वयन करने में बहुत परेशानी होती है। यह इसके लायक नहीं हो सकता है। इसके बजाय बस विधि पैकेज डिफ़ॉल्ट करें।

हालांकि, यदि आप निजी विधि को कॉल करने के लिए दृढ़ हैं, तो आप प्रतिबिंब के माध्यम से कॉल की अनुमति देने के लिए Decapsulated_something कक्षा में setAccessible का उपयोग कर सकते हैं। तो यह काफी सरल है।

+0

+1। – Thilo

1

मैं "सामान्य में" प्रश्न का उत्तर दूंगा :-) यह प्रतिबिंब के माध्यम से विधि को सुलभ बनाने के लिए कोड की कुछ पंक्तियां लेता है और वहां कई पुस्तकालयों, उपयोगिताएं, एपीआई आदि हैं जो करने के तरीके प्रदान करते हैं इसलिए। संभवतः कई अलग-अलग तकनीकें भी हैं जिनका आप अपने कोड में उपयोग कर सकते हैं। उदाहरण के लिए बाइटकोड मैनिपुलेशन, प्रतिबिंब, कक्षा एक्सटेंशन इत्यादि। लेकिन मैं चीजों को सरल रखने के इच्छुक हूं। हालांकि निजी तरीकों का परीक्षण करने के लिए यह उपयोगी हो सकता है, यह भी संभावना है कि आप केवल कुछ परीक्षण करना चाहेंगे। तो कुछ जटिल इंजीनियरिंग इंजीनियरिंग शायद अधिक है। मैं सिर्फ एक स्थापित एपीआई का उपयोग करता हूं, या उस निजी विधि को एक्सेस करने के लिए एक त्वरित विधि लिखता हूं जिसमें मुझे रूचि थी और इसे उस पर करने दें।

1

दृष्टिकोण की संख्या में लेने के लिए

  • निजी तरीकों का परीक्षण नहीं है के रूप में वे कार्यान्वयन विवरण जो फोन करने वाले के लिए एक फर्क कभी नहीं करना चाहिए छिपे हुए हैं कर रहे हैं।
  • विधियों को पैकेज स्थानीय बनाएं ताकि एक कॉलर उन्हें एक्सेस न कर सके, लेकिन आप उन्हें उसी पैकेज में एक्सेस कर सकते हैं यानी यूनिट टेस्ट।
  • इकाई को एक आंतरिक कक्षा का परीक्षण करें या स्थानीय आंतरिक कक्षा पैकेज प्रदान करें। यकीन नहीं है कि यह एक सुधार है!
  • कक्षा के तरीकों तक पहुंचने के लिए प्रतिबिंब का उपयोग करें। यह एक विधि rpivate चिह्नित करने की तरह है जब यह नहीं है और एक भ्रम IMHO है। जब आप वास्तव में निजी होते हैं तो आपको केवल एक विधि को निजी रूप से चिह्नित करना चाहिए।
1

मैंने कुछ साल पहले एक परियोजना पर काम किया था जिससे कक्षाएं उत्पन्न हुईं ताकि यूनिट परीक्षण निजी तरीकों को आसान बना दिया जा सके। http://java.net/projects/privateer/

यह अतिरिक्त कक्षाएं उत्पन्न करता है जो प्रतिबिंब को कॉल करने से आसान बनाता है, उदाहरण के लिए अगर आपके पास MyClass.myPrivateMethod() था, तो यह _MyClass क्लास उत्पन्न करेगा जो सीधे myPrivateMethod के आमंत्रण की अनुमति देगा।

यह वास्तव में कभी खत्म नहीं हुआ था और कुछ मामलों के लिए उपयोगी था, लेकिन समग्र रूप से मैं पूरी तरह से आवश्यक होने तक निजी तरीकों का परीक्षण करने की सिफारिश नहीं करता। आम तौर पर उन्हें उपयोगिता वर्गों में फिर से डिजाइन करना (यदि आप उन्हें उपयोग करने वाले उपयोगकर्ताओं के बारे में चिंतित हैं तो पैकेज एक्सेस के साथ) एक बेहतर विकल्प है।

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