निजी कंस्ट्रक्टर में टेस्ट कवरेज कैसे जोड़ें?


110

यह कोड है:

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
  }
}

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


यह मुझे ऐसा लगता है जैसे आप सिंगलटन पैटर्न को लागू करने की कोशिश कर रहे हैं। यदि हां, तो आप dp4j.com को पसंद कर सकते हैं (जो बिल्कुल ऐसा करता है)
simpatico

"जानबूझकर खाली" को अपवाद को फेंकने के साथ नहीं बदलना चाहिए? उस मामले में आप परीक्षण लिख सकते हैं जो विशिष्ट संदेश के साथ उस विशिष्ट अपवाद की अपेक्षा करते हैं, नहीं? यकीन है कि अगर यह overkill है नहीं
Ewoks

जवाबों:


85

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

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

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


18
मैं इस विशेष
रचनाकार की

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

19
@JonSkeet: मैं पूरी तरह से "एक उपकरण के लिए गुलाम मत बनो" से सहमत हूं, लेकिन हर परियोजना में "दोष गणना" को याद रखना अच्छा नहीं है। कैसे सुनिश्चित करें कि 7/9 परिणाम कोबेरटुरा सीमा है, और प्रोग्रामर नहीं है? क्लास-दर-क्लास की जाँच करने के लिए एक नए प्रोग्रामर को हर विफलता (जो कि बड़ी परियोजनाओं में बहुत हो सकती है) दर्ज करनी चाहिए।
एडुआर्डो कोस्टा

5
इस सवाल का जवाब नहीं है। और वैसे, कुछ प्रबंधक कवरेज संख्या को देखते हैं। वे परवाह क्यों नहीं करते। वे जानते हैं कि 85% 75% से बेहतर है।
एसीवी

2
परीक्षण करने के लिए एक व्यावहारिक उपयोग का मामला अन्यथा दुर्गम कोड 100% परीक्षण कवरेज प्राप्त करना है ताकि किसी को फिर से उस वर्ग को न देखना पड़े। यदि कवरेज 95% पर अटका हुआ है, तो कई डेवलपर्स इसके कारण का पता लगाने का प्रयास कर सकते हैं, बस इस मुद्दे पर बार-बार टकरा सकते हैं।
thisismydesign

140

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

@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();
}

25
लेकिन यह कवरेज रिपोर्ट में शोर को टेस्ट सूट में जोड़कर शोर को खत्म कर रहा है । मैंने "आदर्शवाद को एक तरफ रखकर" वाक्य को समाप्त कर दिया होगा। :)
क्रिस्टोफर ऑर्ट

11
इस परीक्षण को किसी भी प्रकार का अर्थ देने के लिए, आपको संभवतः यह भी दावा करना चाहिए कि कंस्ट्रक्टर का पहुंच स्तर वह है जो आप इसकी अपेक्षा करते हैं।
जेरेमी

बुराई प्रतिबिंब प्लस जेरेमी के विचारों के साथ-साथ "testIfConstructorIsPStreetWithoutRaisingException" जैसे सार्थक नाम को जोड़ते हुए, मुझे लगता है कि यह "द" उत्तर है।
एडुआर्डो कोस्टा

1
यह वाक्यात्मक रूप से गलत है क्या यह नहीं है? क्या है constructor? Constructorपैरामीटर नहीं होना चाहिए और एक कच्चा प्रकार नहीं होना चाहिए ?
एडम पार्किं

2
यह गलत है: constructor.isAccessible()हमेशा एक सार्वजनिक निर्माणकर्ता पर भी गलत रिटर्न देता है। एक का उपयोग करना चाहिए assertTrue(Modifier.isPrivate(constructor.getModifiers()));
टिमोमिनेन

78

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

/**
 * 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 में रखा है


11
+1 यह न केवल टूल को ट्रिक किए बिना समस्या को हल करता है, बल्कि यह एक उपयोगिता वर्ग स्थापित करने के कोडिंग मानकों का पूरी तरह से परीक्षण करता है। मुझे उपयोग करने के लिए एक्सेसिबिलिटी टेस्ट को बदलना पड़ा Modifier.isPrivateक्योंकि कुछ मामलों में निजी कंस्ट्रक्टरों के लिए isAccessibleलौट रहा था true(लाइब्रेरी हस्तक्षेप का मजाक उड़ा रहा था)।
डेविड हार्कस

4
मैं वास्तव में इसे JUnit के Assert वर्ग में जोड़ना चाहता हूं, लेकिन आपके काम का श्रेय नहीं लेना चाहता। मुझे लगता है कि यह बहुत अच्छा है। यह Assert.utilityClassWellDefined()JUnit 4.12+ में होना बहुत अच्छा होगा । क्या आपने पुल अनुरोध पर विचार किया है?
विजनरी सॉफ्टवेयर सॉल्यूशंस

ध्यान दें कि setAccessible()कंस्ट्रक्टर को सुलभ बनाने के लिए उपयोग करने से सोनार के कोड कवरेज टूल (जब मैं ऐसा करता हूं तो क्लास सोनार के कोड कवरेज रिपोर्ट से गायब हो जाता है) के लिए समस्या खड़ी हो जाती है।
एडम पार्किन

धन्यवाद, मैं हालांकि सुलभ ध्वज को रीसेट कर देता हूं। शायद यह सोनार पर ही एक बग है?
आर्किमिडीज ट्रेजानो

मैंने अपने बैटिक मावेन प्लगइन पर कवरेज के लिए अपनी सोनार रिपोर्ट को देखा, यह सही ढंग से कवर करने के लिए लगता है। site.trajano.net/batik-maven-plugin/cobertura/index.html
Archimedes Trajano

19

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

@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% विधि कवरेज के गर्म फजी लग रहा है।


ओवरकिल हो सकता है, लेकिन अगर यह यूनिट्स या इसी तरह का था, तो मैं इसका इस्तेमाल करूंगा
स्टीवर्ट

+1 अच्छी शुरुआत, हालांकि मैं आर्किमिडीज के अधिक पूर्ण परीक्षण के साथ गया था ।
डेविड हार्कस

पहला उदाहरण काम नहीं करता है - IllegalAccesException का मतलब है कि कंस्ट्रक्टर को कभी नहीं बुलाया जाता है, इसलिए कवरेज रिकॉर्ड नहीं किया जाता है।
टॉम मैकइंटायर

IMO, पहले कोड स्निपेट में समाधान इस चर्चा में सबसे साफ और सरल है। बस लाइन fail(...)जरूरी नहीं है।
पिओत्र विट्चेन

9

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

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

package com.XXX;

public interface Foo {

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

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


1
दुर्भाग्य से, हालांकि, आप इंटरफ़ेस को "अंतिम" घोषित नहीं कर सकते हैं, किसी को भी इसे उपवर्ग से रोकना - अन्यथा यह सबसे अच्छा तरीका होगा।
माइकल बेरी

5

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

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

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

    @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());
        }
    }
और फिर जैसे-जैसे आप जाते हैं सरणी में कक्षाएं जोड़ें।


5

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

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

तुच्छ को अनदेखा करें

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

<cobertura-instrument ignoreTrivial="true" />

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

cobertura {
    coverageIgnoreTrivial = true
}

4

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

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

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


3

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

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

हालांकि उस कक्षा का परीक्षण कैसे किया जाता है जो हालांकि प्रश्न में तैनात है? आपको यह नहीं मान लेना चाहिए कि आप निजी कंस्ट्रक्टर के साथ हर वर्ग को एनम में बदल सकते हैं, या आप चाहते हैं।
जॉन स्कीट

@JonSkeet मैं प्रश्न में वर्ग के लिए कर सकता हूं। और अधिकांश उपयोगिता वर्ग जिनमें केवल स्थैतिक विधियों का गुच्छा है। अन्यथा केवल निजी कंस्ट्रक्टर वाले वर्ग का कोई मतलब नहीं है।
कान

1
निजी निर्माणकर्ता के साथ एक वर्ग को सार्वजनिक स्थैतिक विधियों से त्वरित किया जा सकता है, हालांकि तब कवरेज प्राप्त करना आसान होता है। लेकिन मूल रूप से मैं किसी भी वर्ग को पसंद करूंगा जो Enum<E>वास्तव में एक एनम हो सकता है ... मेरा मानना ​​है कि इससे इरादों का बेहतर पता चलता है।
जॉन स्कीट

4
वाह, मैं बिल्कुल कोड पसंद करूंगा, जो एक सुंदर मनमानी संख्या पर समझ में आता है। (कवरेज गुणवत्ता की कोई गारंटी नहीं है, न ही सभी मामलों में 100% कवरेज संभव है। आपके परीक्षणों को आपके कोड को सर्वोत्तम रूप से निर्देशित करना चाहिए - विचित्र इरादों की एक चट्टान पर इसे चलाने की जरूरत नहीं है।)
जॉन स्कीट

1
@Kan: टूल को ब्लफ़ करने के लिए कंस्ट्रक्टर को डमी कॉल जोड़ना आशय नहीं होना चाहिए। जो भी परियोजना की भलाई के निर्धारण के लिए एकल मीट्रिक पर निर्भर है, पहले से ही विनाश की राह पर है।
अपूर्व खुरसिया

1

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


1

एक अन्य विकल्प निम्नलिखित कोड के समान एक स्थिर इनिशियलाइज़र बनाना है

class YourClass {
  private YourClass() {
  }
  static {
     new YourClass();
  }

  // real ops
}

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


मैं इसे काफी कम करता हूं। सस्ते में सस्ते, गंदे के रूप में सस्ते, लेकिन प्रभावी।
फॉल्सर

सोनार के साथ, यह वास्तव में वर्ग को पूरी तरह से कोड कवरेज से याद करने का कारण बनता है।
एडम पार्किं

1

ClassUnderTest testClass = Whitebox.invokeConstructor (ClassUnderTest.class);


यह सही उत्तर होना चाहिए था क्योंकि यह ठीक उसी तरह से उत्तर देता है जैसा पूछा जाता है।
चाकियन

0

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

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


0

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

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

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

उदाहरण के लिए, यदि मेरे [निजी] कंस्ट्रक्टर ने मेरी कक्षा के इंस्टेंस फ़ील्ड aको सेट किया है 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कंस्ट्रक्टर के सटीक हस्ताक्षर के साथ रखें।

<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>

0
@Test
public void testTestPrivateConstructor() {
    Constructor<Test> cnt;
    try {
        cnt = Test.class.getDeclaredConstructor();
        cnt.setAccessible(true);

        cnt.newInstance();
    } catch (Exception e) {
        e.getMessage();
    }
}

Test.java आपकी सोर्स फाइल है, जिसमें आपका प्राइवेट कंस्ट्रक्टर है


यह व्याख्या करना अच्छा होगा कि यह निर्माण कवरेज में मदद क्यों करता है।
मार्कस

सच है, और दूसरी बात: आपके परीक्षा में अपवाद क्यों? फेंका जा रहा अपवाद वास्तव में परीक्षण को विफल कर देना चाहिए।
जोडी

0

निम्नलिखित ने मुझे लोम्बोक एनोटेशन @ यूटिलिटीक्लास के साथ बनाए गए एक वर्ग पर काम किया, जो स्वचालित रूप से एक निजी कंस्ट्रक्टर जोड़ देता है।

@Test
public void testConstructorIsPrivate() throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException {
    Constructor<YOUR_CLASS_NAME> constructor = YOUR_CLASS_NAME.class.getDeclaredConstructor();
    assertTrue(Modifier.isPrivate(constructor.getModifiers())); //this tests that the constructor is private
    constructor.setAccessible(true);
    assertThrows(InvocationTargetException.class, () -> {
        constructor.newInstance();
    }); //this add the full coverage on private constructor
}

हालाँकि कंस्ट्रक्टर। SetAccessible (सच) को तब काम करना चाहिए जब निजी कंस्ट्रक्टर को मैन्युअल रूप से लिखा गया हो, क्योंकि लोम्बोक एनोटेशन काम नहीं करता है, क्योंकि यह इसे बाध्य करता है। Constructor.newInstance () वास्तव में परीक्षण करता है कि कंस्ट्रक्टर को आमंत्रित किया गया है और यह कॉस्ट्रोक्टर के कवरेज को पूरा करता है। मुखरता के साथ आप रोकते हैं कि परीक्षण विफल हो गया है और आपने अपवाद को प्रबंधित किया है क्योंकि ठीक वही त्रुटि है जिसकी आप अपेक्षा करते हैं। यद्यपि यह एक वर्कअराउंड है और मैं "लाइन कवरेज" बनाम "कार्यक्षमता / व्यवहार कवरेज" की अवधारणा की सराहना नहीं करता, हम इस परीक्षण पर समझ पा सकते हैं। वास्तव में आपको यकीन है कि यूटिलिटी क्लास वास्तव में एक निजी कंस्ट्रक्टर है जो कि एक अपवाद को सही ढंग से फेंकता है जब रिफ्लेक्शन के माध्यम से भी आह्वान किया जाता है। उम्मीद है की यह मदद करेगा।


हाय @ शांतेश्वरइंडे। बहुत बहुत धन्यवाद। आपके सुझावों के बाद मेरा इनपुट संपादित और पूर्ण हो गया है। सादर।
रिककर्डो सोलिमेना

0

2019 में मेरा पसंदीदा विकल्प: लुम्बोक का उपयोग करें।

विशेष रूप से, @UtilityClassएनोटेशन । (लेखन के समय केवल "प्रयोगात्मक", लेकिन यह ठीक काम करता है और इसका सकारात्मक दृष्टिकोण है, इसलिए जल्द ही इसे अपग्रेड करने की संभावना है।)

यह एनोटेशन तात्कालिकता को रोकने के लिए निजी निर्माणकर्ता को जोड़ देगा और कक्षा को अंतिम बना देगा। जब बहुत सारे परीक्षण ढाँचों के साथ संयुक्त किया lombok.addLombokGeneratedAnnotation = trueजाता है lombok.config, तो टेस्ट कवरेज की गणना करते समय ऑटो-जेनरेट किए गए कोड को अनदेखा कर देगा, जिससे आप बिना हैक या प्रतिबिंब के उस ऑटो-जेनरेट किए गए कोड के कवरेज को बायपास कर सकेंगे।


-2

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

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


3
वह गलत है; जैसा कि ऊपर उल्लेख किया गया है, आप प्रतिबिंब के माध्यम से इसे त्वरित कर सकते हैं।
Theotherian

यह बुरा है, कभी भी डिफ़ॉल्ट सार्वजनिक निर्माण को दिखाने न दें, आपको इसे रोकने के लिए निजी को जोड़ना चाहिए।
लो बेन बेन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.