2017-08-14 1 views
0

um näher zu 100% zu kommen, würde ich gerne die Hauptmethode testen. Ich erstelle nur eine Instanz einer Klasse, die die Anwendung starten soll. Test und Code sieht so aus:testen Hauptmethode mit jmockit

public class MainTest { 
    @Test 
    public void delegates_to_Launcher_instance(@Mocked Launcher launcher) { 
     String[] args = {"i"}; 
     Main.main(args); 
     new Verifications() {{ launcher.run(args); }}; 
    } 
} 

public class Main { 
    public static void main(String[] args) { 
     new Launcher().run(args); 
    } 
} 

public class Launcher { 
    public void run(String[] args) { 
    } 
} 

Funktioniert perfekt!

Jetzt ist die Launcher-Klasse ein wenig überflüssig, und Coverage ist nicht 100%, weil der Konstruktor von Main nicht aufgerufen wird. Beide könnten, indem Sie den Code aus Launcher Haupt, wie dies geheilt werden:

public class MainTest { 
    @Test 
    public void delegates_to_Main_instance(@Mocked Main main) { 
     String[] args = {"i"}; 
     Main.main(args); 
     new Verifications() {{ main.run(args); }}; 
    } 
} 

public class Main { 
    public static void main(String[] args) { 
     new Main().run(args); 
    } 
} 

Aber wenn ich das tue, JMockit klagt mit:

Missing invocation to: 
mmm.Main#run(["i"]) 
    on mock instance: [email protected] 

    at mmm.MainTest$1.<init>(MainTest.java:15) 
    at mmm.MainTest.delegates_to_Main_instance(MainTest.java:15) 
Caused by: Missing invocation 
    at mmm.Main.run(Main.java) 
    ... 2 more 

Kann jemand erklären, was hier vor sich geht?

+0

Nicht verwandt: Lesen Sie über Java-Namenskonventionen. Verwenden von _ ist nur für SOME_CONSTANTS - aber "_" geht nicht in Methodennamen! – GhostCat

+0

GhostCats Antworten sind korrekt. Ich werde nur hinzufügen, dass die ganze Idee, hier zu spotten, schlecht ist. Ein guter Test bestätigt, dass eine gegebene Klasse "A" das * große geschäftliche Problem löst *, das es lösen soll, * nicht *, dass es irgendeine Methode in der Klasse "B" aufruft. Außerdem sollten Tests nicht geschrieben werden, um die * Code * Abdeckung zu erhöhen, sondern um die Abdeckung von * Geschäftsanforderungen * zu erhöhen. Andernfalls enden Sie mit einer Reihe von Tests, die nicht nur von geringem Wert sind, sondern auch Sie/andere davon abhalten, die tatsächlich relevanten Tests zu erstellen. Spott ist nur in besonderen Fällen nützlich - darüber hinaus ist es schädlich. –

Antwort

1

hier:

public void delegates_to_Main_instance(@Mocked Main main) { 

Du Haupt spöttisch. Gleichzeitig möchten Sie einen Komponententest schreiben, der das main Objekt ausübt. Das ergibt keinen Sinn. Sie nur Mock Dinge, die in Ihren Produktionscode gehen und die Sie steuern/verifizieren müssen. Sie tun nicht verspotten Sie das Objekt, das Sie selbst testen wollen!

In Ihrem ersten Beispiel verwenden Sie eine gespottete Launcher, die an die getestete Klasse weitergegeben wird. Macht perfekt Sinn. Im zweiten Beispiel übergeben Sie eine mocked-Instanz und nehmen dann an, dass die mocked-Instanz die getestete Klasse ist. Macht nicht so viel Sinn.