2017-08-14 2 views
0

pour se rapprocher de 100%, je voudrais tester la méthode principale. Je crée uniquement une instance d'une classe, qui doit démarrer l'application. Test et le code ressemble à ceci:tester la méthode principale avec 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) { 
    } 
} 

Fonctionne parfaitement! Maintenant, la classe Launcher est un peu superflue, et la couverture n'est pas de 100%, car le constructeur de Main n'est pas appelé. Les deux peuvent être guéries en déplaçant le code de lanceur à principal, comme ceci:

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

Mais quand je fais cela, JMockit se plaint avec:

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 

Quelqu'un peut-il expliquer, ce qui se passe ici?

+0

Sans lien: lisez les conventions de dénomination Java. Utiliser _ est seulement pour SOME_CONSTANTS - mais "_" ne va pas dans les noms de méthodes! – GhostCat

+0

Les réponses de GhostCat sont correctes. J'ajouterai seulement que l'idée d'utiliser la moquerie ici est mauvaise. Un bon test vérifie qu'une classe donnée "A" résout le * problème commercial * sérieux qu'elle est censée résoudre, * pas * qu'elle n'appelle une méthode en classe "B". En outre, les tests ne doivent pas être écrits pour augmenter la couverture * code *, mais pour augmenter la couverture des * exigences métier *. Sinon, vous vous retrouvez avec un tas de tests qui non seulement ont peu de valeur, mais qui vous découragent, vous ou d'autres, de créer ces tests qui comptent réellement. Le moqueur n'est utile que dans des cas particuliers - au-delà de tout cela est nuisible. –

Répondre

1

ici:

public void delegates_to_Main_instance(@Mocked Main main) { 

Vous moquez principale. Dans le même temps, vous voulez écrire un test unitaire qui exerce cet objet main. Cela n'a pas de sens. Vous seulement mock choses qui vont dans votre code de production et que vous devez contrôler/vérifier. Vous faites pas simulez l'objet que vous avez l'intention de tester lui-même!

Dans votre premier exemple, vous utilisez un Launcher raillé qui est transmis à la classe testée. Cela a un sens parfait. Dans le deuxième exemple, vous passez une instance simulée et supposons que l'instance simulée est la classe testée. Ça n'a pas tellement de sens.