2015-01-02 12 views
9

In un progetto, ho una classe di utilità che assomiglia a questo:Come escludere il codice sorgente dalla misurazione della copertura in IntelliJ IDEA?

public final class Util { 
    private Util() {} 
    public static String method1(InputStream in) {...} 
    public static String method2(BufferedReader in) {...} 
    public static String method3(File file) {...} 
} 

La classe è una classe di utilità, nel senso che essa contiene solo static metodi. Pertanto è dichiarato final e il suo costruttore è private. Creare istanze o derivare sottoclassi semplicemente non avrebbe alcun senso.

Ho una suite di test unitari che testa il progetto. Sto usando IntelliJ IDEA per eseguire i test, misurare e visualizzare la copertura del codice. Il costruttore dell'utilità class Util ora riduce la copertura. Mi piacerebbe vedere un 100% di copertura logica al 100%. Il codice come il costruttore privato della classe Utility riduce la copertura.

Esiste la possibilità, preferibilmente mediante un'annotazione, di contrassegnare un metodo o costruttore come non rilevante per la copertura del codice al fine di escludere tale codice dai report di copertura e ottenere così una copertura del 100% visualizzata?

So che in generale nascondere il codice dal rapporto di copertura è a proprio svantaggio. Non mi dispiacerebbe se il rapporto avesse una lista di "articoli ignorati" - in realtà, sarebbe bello, per verificare se qualcuno sta ignorando cose che non dovrebbero essere ignorate. Il punto riguarda davvero il codice per il quale la copertura non ha senso, come il costruttore privato di una classe di utilità.

Ho provato a trovare se annotations.jar contiene un candidato. L'unica annotazione che sembrava anche lontanamente come se potesse farlo era TestOnly, ma non soddisfa questo scopo. Ho anche dato un'occhiata in plugins/coverage/lib/*.jar e non sono riuscito a trovare un candidato, ma forse l'ho perso?

+1

appari interpretare il rapporto di copertura sbagliato. Il codice non coperto potrebbe essere interpretato come se necessitasse di più test, o potrebbe essere considerato un'indicazione di un odore di codice. In questo caso, è un odore: dovresti davvero evitare classi di utilità come questa, è più che probabile un artefatto di cattiva progettazione e dovresti provare a risolvere quello piuttosto che il tuo report di copertura. Rapporti di gioco come questo sono uno dei maggiori problemi con i programmi di metrica, e se tu fossi nel mio team parleremmo di quello che pensi di fare adesso. –

+1

Per qualcuno che non conosce il vero codice in questione, penso che tu stia usando un linguaggio piuttosto forte e dogmatico. Sono d'accordo sul fatto che le classi di utilità possono essere un odore e le persone dovrebbero essere avvertite su di loro. Ma solo perché qualcosa è spesso cattiva, non significa che sia sempre male. Ad ogni modo, usando 'enum' ora, come suggerito da Peter Lawrey. Ed è perfettamente logico, poiché si tratta di una classe con un insieme di istanze predefinito (vuoto) e la copertura è felice ora. P.S .: Felice di parlare se nella tua squadra. Non mi sentirei più solo a predicare il Codice Pulito. –

risposta

9

Io uso enum per le classi di utilità e la maggior parte degli strumenti di copertura sanno ignorare i suoi metodi.

public enum Util { ; 

enum sono final con private costruttori per impostazione predefinita.

+0

Ho provato questo, e funziona! Ho anche provato a usare un'interfaccia ', ma funziona solo se non ci sono metodi' static statici '. Mi aiuta nella situazione attuale. Sto ancora sperando in una soluzione più generica. –

+0

Puoi aggiungere test fittizi o classi nidificate per chiamare metodi privati ​​per ottenere il 100% –

+0

Hai ragione, potrei, ma è qualcosa che volevo evitare. –

3

Questa domanda ha attualmente più di un anno; tuttavia, pensavo di poter offrire un'alternativa all'ignorare i costruttori privati ​​nei test unitari. Sebbene abbastanza improbabile, è possibile aggirare un costruttore privato in Java. Inoltre, è possibile che la classe possa essere modificata in futuro, qualcuno potrebbe aggiungere un costruttore ecc. Avere un test unitario per verificarlo può sembrare ridondante, ma aggiunge un altro livello di chiarezza d'intento. Un test dell'unità fallito catturerebbe sicuramente la mia attenzione, "Ho fatto fallire un test unitario, sono sicuro di sapere cosa sto cambiando qui?"

Senza ulteriori indugi ecco alcuni esempi di codice.

Qui abbiamo una classe con un costruttore privato.

public final class ClassWithPrivateCtor 
{ 
    private ClassWithPrivateCtor() 
    { 
    throw new AssertionError(String.format(
     "Illegal instantiation of class: %s.", 
     this.getClass().getName())); 
    } 
} 

Questo è un modo per richiamare un costruttore privato in Java.

private static <T> void invokePrivateConstructor(final Class<T> type) 
    throws Throwable 
{ 
    final Constructor<T> constructor = type.getDeclaredConstructor(); 

    constructor.setAccessible(true); 

    try 
    { 
    constructor.newInstance(); 
    } 
    catch (InvocationTargetException ex) 
    { 
    throw ex.getTargetException(); 
    } 
} 

Ed è così che lo uso nei miei test di unità.

@Test(
    description = "Verify ClassWithPrivateCtor private constructor fails.", 
    expectedExceptions = AssertionError.class) 
public void classWithPrivateCtorTest() 
    throws Throwable 
{ 
    invokePrivateConstructor(ClassWithPrivateCtor.class); 
} 

ho fatto l'abitudine di verificare i costruttori privati ​​in questo modo solo per essere chiari circa l'intento originale della classe se la sua una classe di utilità o di una classe con costanti ecc ...

Problemi correlati