दिलचस्प पोस्ट
बैच-फ़ाइल से चलाएं Ajax.ActionLink का उपयोग कैसे करें? मैं कैसे NHibernate केवल इसे निष्पादित बिना एसक्यूएल उत्पन्न कर सकते हैं? क्या $ मिलियन का एक संस्करण है जो कॉल वापस उपयोग नहीं करता है? आईओएस फ़ायरबेज पुश नोटिफिकेशन: फायरबेज उपयोगकर्ता के डिवाइस टोकन और नोटिफिकेशन भेजने के लिए कैसे करें मिश्रित सामग्री को अनुमति देने के लिए क्रोम कैसे प्राप्त करें? क्या आपको सर्वर साइड पर सत्यापन करना चाहिए? एंड्रॉइड: कोई पूर्ण पाठ दर्ज नहीं होने पर स्वत: पूर्ण पाठक सुझाव दिखाएं "इंटरफेस के लिए प्रोग्राम, कार्यान्वयन नहीं" का क्या अर्थ है? Android UI में गोल आयत कैसे आकर्षित करें? फोकस होने पर सभी टेक्स्ट को संपादन टेक्स्ट के अंदर चुनें UITextView को छवियां जोड़ना क्या हमें * सापेक्ष * त्रुटि के खिलाफ समानता के लिए अस्थायी बिंदु संख्याओं की तुलना करनी चाहिए? मैं आईओएस के लिए फोनगैप में यह स्क्रिप्ट कैसे स्थापित करूं? निर्भरता के साथ एक जार बनाने के लिए Gradle का उपयोग करना

निजी कंस्ट्रक्टर को कैसे परीक्षण कवरेज जोड़ने के लिए?

यह कोड है:

package com.XXX; public final class Foo { private Foo() { // intentionally empty } public static int bar() { return 1; } } 

यह परीक्षण है:

 package com.XXX; public FooTest { @Test void testValidatesThatBarWorks() { int result = Foo.bar(); assertEquals(1, result); } @Test(expected = java.lang.IllegalAccessException.class) void testValidatesThatClassFooIsNotInstantiable() { Class cls = Class.forName("com.XXX.Foo"); cls.newInstance(); // exception here } } 

ठीक काम करता है, कक्षा का परीक्षण किया जाता है। लेकिन कोबेर्टुरा का कहना है कि कक्षा के निजी निर्माता के शून्य कोड कवरेज है। हम ऐसे निजी कन्स्ट्रक्टर को कैसे परीक्षण कवरेज जोड़ सकते हैं?

Solutions Collecting From Web of "निजी कंस्ट्रक्टर को कैसे परीक्षण कवरेज जोड़ने के लिए?"

ठीक है, ऐसे तरीके हैं जो आप संभावित रूप से प्रतिबिंब आदि का उपयोग कर सकते हैं – लेकिन क्या यह वास्तव में इसके लायक है? यह एक कन्स्ट्रक्टर है जिसे कभी भी कहा नहीं जाना चाहिए, सही है?

अगर कोई एनोटेशन या कुछ समान है तो आप कोबर्टुरा को समझने के लिए क्लास में जोड़ सकते हैं कि इसे कॉल नहीं किया जाएगा, ऐसा करें: मुझे नहीं लगता कि यह कूपन को कृत्रिम रूप से जोड़ने के लिए हूप्स के माध्यम से जाने योग्य है।

संपादित करें: अगर ऐसा करने का कोई तरीका नहीं है, तो बस थोड़ा कम कवरेज के साथ रहें। याद रखें कि कवरेज का मतलब कुछ ऐसा है जो आपके लिए उपयोगी है – आपको उपकरण के प्रभार में होना चाहिए, न कि अन्य तरह का दौर।

मैं जॉन स्कीट से पूरी तरह सहमत नहीं हूं मुझे लगता है कि यदि आप अपनी कवरेज रिपोर्ट में शोर को खत्म करने और कवरेज देने के लिए एक आसान जीत प्राप्त कर सकते हैं, तो आपको इसे करना चाहिए या तो कन्स्ट्रक्टर की अनदेखी करने के लिए अपने विचार उपकरण को बताएं या आदर्शवाद को अलग रखें और निम्नलिखित परीक्षण लिखें और इसके साथ करें:

 @Test public void testConstructorIsPrivate() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { Constructor<Foo> constructor = Foo.class.getDeclaredConstructor(); assertTrue(Modifier.isPrivate(constructor.getModifiers())); constructor.setAccessible(true); constructor.newInstance(); } 

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

 /** * Verifies that a utility class is well defined. * * @param clazz * utility class to verify. */ public static void assertUtilityClassWellDefined(final Class<?> clazz) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { Assert.assertTrue("class must be final", Modifier.isFinal(clazz.getModifiers())); Assert.assertEquals("There must be only one constructor", 1, clazz.getDeclaredConstructors().length); final Constructor<?> constructor = clazz.getDeclaredConstructor(); if (constructor.isAccessible() || !Modifier.isPrivate(constructor.getModifiers())) { Assert.fail("constructor is not private"); } constructor.setAccessible(true); constructor.newInstance(); constructor.setAccessible(false); for (final Method method : clazz.getMethods()) { if (!Modifier.isStatic(method.getModifiers()) && method.getDeclaringClass().equals(clazz)) { Assert.fail("there exists a non-static method:" + method); } } } 

मैंने https://github.com/trajano/maven-jee6/tree/master/maven-jee6-test में पूर्ण कोड और उदाहरण रख दिए हैं

मैंने चेकस्टाइल को संतुष्ट करने के लिए, स्थिर उपयोगिता कार्यों के अपने वर्ग के निर्माता को निजी बना दिया था। लेकिन मूल पोस्टर की तरह, मुझे कोबर्टुरा ने परीक्षण के बारे में शिकायत करनी थी। सबसे पहले मैंने इस दृष्टिकोण की कोशिश की, लेकिन यह कवरेज रिपोर्ट को प्रभावित नहीं करता क्योंकि कन्स्ट्रक्टर वास्तव में निष्पादित नहीं होता है। तो वास्तव में यह सब परीक्षण है कि कन्स्ट्रक्टर निजी शेष है – और इसके बाद के परीक्षण में पहुंच की जांच से बेमानी हो गई है।

 @Test(expected=IllegalAccessException.class) public void testConstructorPrivate() throws Exception { MyUtilityClass.class.newInstance(); fail("Utility class constructor should be private"); } 

मैं जाविद जमैके के सुझाव के साथ गया और प्रतिबिंब लगाया, लेकिन क्लास की जांच के साथ किसी को भी गड़बड़ने के लिए जोड़ा गया (और उच्च स्तर के ईविल को इंगित करने के लिए परीक्षण का नाम दिया गया)।

 @Test public void evilConstructorInaccessibilityTest() throws Exception { Constructor[] ctors = MyUtilityClass.class.getDeclaredConstructors(); assertEquals("Utility class should only have one constructor", 1, ctors.length); Constructor ctor = ctors[0]; assertFalse("Utility class constructor should be inaccessible", ctor.isAccessible()); ctor.setAccessible(true); // obviously we'd never do this in production assertEquals("You'd expect the construct to return the expected type", MyUtilityClass.class, ctor.newInstance().getClass()); } 

यह इतना अधिक है, लेकिन मुझे स्वीकार करना होगा कि मुझे 100% विधि कवरेज के गर्म फजी महसूस करना पसंद है।

परीक्षण कोड के पीछे तर्क, जो कुछ भी नहीं करता, 100% कोड कवरेज हासिल करना है और जब कोड कवरेज बूँदें। अन्यथा कोई हमेशा सोच सकता है, हे मेरे पास अब 100% कोड कवरेज नहीं है, लेकिन यह मेरे निजी कन्स्ट्रक्टर की वजह से है। यह बिना जांच न किए गए विधियों को खोजना आसान बनाता है, यह जांचने के लिए कि यह सिर्फ एक निजी निर्माता था। जैसा कि आपका कोडबेस बढ़ता है, आपको वास्तव में 99% की बजाए 100% की ओर देखकर अच्छा गर्म महसूस होगा।

आईएमओ यह प्रतिबिंब का उपयोग करने के लिए सबसे अच्छा है क्योंकि अन्यथा आप को एक बेहतर कोड कवरेज उपकरण प्राप्त करना होगा जो इन कंस्ट्रक्टरों को अनदेखा कर लेते हैं या किसी तरह तरीके से (शायद एक एनोटेशन या कॉन्फ़िगरेशन फ़ाइल) की उपेक्षा करने के लिए कोड कवरेज उपकरण को बताते हैं, क्योंकि तब आप फंसेंगे एक विशिष्ट कोड कवरेज उपकरण के साथ

एक संपूर्ण दुनिया में सभी कोड कवरेज उपकरण उन निजी कन्स्ट्रक्टरों की अनदेखी करेंगे जो एक अंतिम श्रेणी के होते हैं क्योंकि कन्स्ट्रक्टर एक "सुरक्षा" उपाय के रूप में कुछ और नहीं है 🙂
मैं इस कोड का उपयोग करेगा:

  @Test public void callPrivateConstructorsForCodeCoverage() throws SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException { Class<?>[] classesToConstruct = {Foo.class}; for(Class<?> clazz : classesToConstruct) { Constructor<?> constructor = clazz.getDeclaredConstructor(); constructor.setAccessible(true); assertNotNull(constructor.newInstance()); } } 

और फिर बस सरणी को कक्षाएं जोड़ते हैं जैसे आप जाते हैं।

जावा 8 के साथ, अन्य समाधान खोजने के लिए संभव है।

मुझे लगता है कि आप बस कुछ सार्वजनिक स्थिर विधियों के साथ उपयोगिता वर्ग बनाना चाहते हैं। यदि आप जावा 8 का उपयोग कर सकते हैं, तो आप इसके बजाय interface उपयोग कर सकते हैं।

 package com.XXX; public interface Foo { public static int bar() { return 1; } } 

कोई निर्माता नहीं है और कोबर्टुरा से कोई शिकायत नहीं है। अब आपको केवल उन पंक्तियों का परीक्षण करने की ज़रूरत है जिनकी आप सचमुच परवाह करते हैं।

कोबर्टुरा के नए संस्करणों में छोटे गलतियों / सेटर्स / कन्स्ट्रक्टरों को नजरअंदाज करने के लिए अंतर्निहित समर्थन दिया गया है:

https://github.com/cobertura/cobertura/wiki/Ant-Task-Reference#ignore-trivial

तुच्छ पर ध्यान न दें

तुच्छ को नजरअंदाज करना कन्स्ट्रक्टर / विधियों को बाहर करने की क्षमता की अनुमति देता है जिसमें कोड की एक पंक्ति होती है। कुछ उदाहरणों में सुपर कॉन्स्ट्रक्टर को कॉल, गेटर / सेटर पद्धतियां आदि शामिल हैं। दुर्लभ तुच्छ तर्कों को शामिल करने के लिए निम्नलिखित जोड़ें:

 <cobertura-instrument ignoreTrivial="true" /> 

या एक ग्रैडल बिल्ड में:

 cobertura { coverageIgnoreTrivial = true } 

अंत में, समाधान है!

 public enum Foo {; public static int bar() { return 1; } } 

मत करो। एक खाली कन्स्ट्रक्टर का परीक्षण करने में क्या बात है? कोबर्टुरा 2.0 के बाद से ऐसे तुच्छ मामलों (सेटर्स / गेटर्स के साथ) को अनदेखा करने का एक विकल्प होता है, आप कोबर्टुरा मैवे प्लगइन में कॉन्फ़िगरेशन अनुभाग जोड़कर इसे सक्षम बना सकते हैं:

 <configuration> <instrumentation> <ignoreTrivial>true</ignoreTrivial> </instrumentation> </configuration> 

वैकल्पिक रूप से आप @CoverageIgnore एनोटेशन का उपयोग कर सकते हैं: @CoverageIgnore

मुझे कोबर्टुरा के बारे में नहीं पता है लेकिन मैं क्लोवर का उपयोग करता हूं और इसका पैटर्न-मिलान बहिष्करण जोड़ने का एक साधन है। उदाहरण के लिए, मेरे पास पैटर्न हैं जो अपाचे-कॉमन्स-लॉगिंग लाइनों को छोड़ देते हैं ताकि वे कवरेज में गिना न जाए।

एक अन्य विकल्प निम्न कोड के समान एक स्थिर प्रारंभिक बनाने के लिए है

 class YourClass { private YourClass() { } static { new YourClass(); } // real ops } 

इस प्रकार निजी निर्माता को परीक्षण माना जाता है, और रनटाइम ओवरहेड मूल रूप से मापने योग्य नहीं है। मैं ईक्लीमा का उपयोग करके 100% कवरेज प्राप्त करने के लिए ऐसा करता हूं, लेकिन संभवतः यह प्रत्येक कवरेज उपकरण के लिए काम करता है। इस समाधान के साथ खामियां, ज़ाहिर है कि आप परीक्षण प्रयोजनों के लिए उत्पादन कोड (स्थिर प्रारंभिक) लिखते हैं

कभी-कभी Cobertura अंक कोड नहीं 'कवर नहीं' के रूप में निष्पादित करने के लिए, उस के साथ कुछ भी गलत नहीं है। आप 100% बजाय 99% कवरेज के साथ क्यों संबंध रखते हैं?

तकनीकी रूप से, हालांकि, आप अभी भी प्रतिबिंब के साथ उस निर्माता को आमंत्रित कर सकते हैं, लेकिन यह मेरे लिए बहुत ही गलत (इस मामले में) लगता है।

अगर मुझे आपके प्रश्न का आशय लगता है तो मैं कहूंगा:

  1. आप वास्तविक कंसल्टेंट्स के लिए उचित चेक चाहते हैं जो वास्तविक कार्य करते हैं, और
  2. आप क्लोवर चाहते हैं कि उपयोग कक्षाओं के लिए खाली कन्स्ट्रक्टर को बाहर कर दें।

1 के लिए, यह स्पष्ट है कि आप चाहते हैं कि सभी शुरुआती कारखाने के तरीकों के माध्यम से किए जाएं। ऐसे मामलों में, आपका परीक्षण कन्स्ट्रक्टर के दुष्प्रभावों का परीक्षण करने में सक्षम होना चाहिए। यह सामान्य निजी विधि परीक्षण की श्रेणी के अंतर्गत आना चाहिए। विधियों को छोटा करें ताकि वे केवल सीमित चीजों की सीमित संख्या (आदर्श रूप से, सिर्फ एक चीज और एक चीज अच्छी तरह से) कर सकें और फिर उन विधियों का परीक्षण करें जो उनपर भरोसा करते हैं।

उदाहरण के लिए, यदि मेरी [निजी] कन्स्ट्रक्टर मेरे क्लास के इंस्टेंस को 5 तक फ़ील्ड सेट करता है तब मैं (या इसके बजाय उसे जांचना चाहिए):

 @Test public void testInit() { MyClass myObj = MyClass.newInstance(); //Or whatever factory method you put Assert.assertEquals(5, myObj.getA()); //Or if getA() is private then test some other property/method that relies on a being 5 } 

2 के लिए, अगर आप यूटिल कक्षाओं के लिए एक सेट नामकरण पैटर्न रखते हैं तो आप यूटिल कन्स्ट्रक्टर को बाहर करने के लिए क्लॉव को कॉन्फ़िगर कर सकते हैं उदाहरण के लिए, अपनी परियोजना में मैं इस तरह से कुछ का उपयोग करता हूं (क्योंकि हम सम्मेलन का पालन करते हैं, सभी यूटिल वर्गों के नामों को यूटील के साथ समाप्त करना चाहिए):

 <clover-setup initString="${build.dir}/clovercoverage.db" enabled="${with.clover}"> <methodContext name="prvtCtor" regexp="^private *[a-zA-Z0-9_$]+Util *( *) *"/> </clover-setup> 

मैंने जानबूझकर एक .* छोड़ दिया है ) क्योंकि इस तरह के कन्स्ट्रक्टर का मतलब अपवाद फेंकने के लिए नहीं है (वे कुछ भी करने के लिए नहीं हैं)

वहां एक तीसरा मामला हो सकता है, जहां आप गैर-उपयोगिता वर्ग के लिए एक खाली कन्स्ट्रक्टर बनाना चाहते हैं। ऐसे मामलों में, मैं सुझाव देता हूं कि आप methodContext के सटीक हस्ताक्षर के साथ एक methodContext करें।

 <clover-setup initString="${build.dir}/clovercoverage.db" enabled="${with.clover}"> <methodContext name="prvtCtor" regexp="^private *[a-zA-Z0-9_$]+Util *( *) *"/> <methodContext name="myExceptionalClassCtor" regexp="^private MyExceptionalClass()$"/> </clover-setup> 

यदि आपके पास ऐसे कई असाधारण वर्ग हैं तो आप सामान्यीकृत निजी कन्स्ट्रक्टर को संशोधित करने का विकल्प चुन सकते हैं, जिसे मैंने सुझाव दिया है और इसे से Util को हटा दिया है। इस मामले में, आपको मैन्युअल रूप से यह सुनिश्चित करना होगा कि आपके कंस्ट्रक्टर के दुष्प्रभावों का अभी भी परीक्षण किया गया है और आपकी क्लास / प्रोजेक्ट में अन्य विधियों के द्वारा कवर किया गया है।

 <clover-setup initString="${build.dir}/clovercoverage.db" enabled="${with.clover}"> <methodContext name="prvtCtor" regexp="^private *[a-zA-Z0-9_$]+ *( *) .*"/> </clover-setup> 
 @Test public void testTestPrivateConstructor() { Constructor<Test> cnt; try { cnt = Test.class.getDeclaredConstructor(); cnt.setAccessible(true); cnt.newInstance(); } catch (Exception e) { e.getMessage(); } } 

Test.java आपकी स्रोत फ़ाइल है, जो आपके निजी कन्स्ट्रक्टर को लेकर है

आप नहीं कर सकते

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