JUNIT test void méthodes

J'ai une classe java pleine de méthodes void, et je veux faire un test unitaire pour obtenir une couverture de code maximale.

, Par exemple j'ai cette méthode :

protected static void checkifValidElements(int arg1,  int arg2) {
    method1(arg1);
    method2(arg1);
    method3(arg1, arg2);
    method4(arg1, arg2);
    method5(arg1);
    method6(arg2);
    method7();
}

Son mal nommé pour une raison parce que j'ai traduit le code pour une meilleure compréhension. Chaque méthode vérifie si les arguments sont valides d'une manière ou d'une autre et sont bien écrits.

Exemple :

private static void method1(arg1) {
    if (arg1.indexOf("$") == -1) {

        //Add an error message 
        ErrorFile.errorMessages.add("There is a dollar sign in the specified parameter");
    }
}

Mon test unitaire couvre bien les petites méthodes car je leur demande de vérifier si le fichier ErrorFile contient l'erreur message, mais je ne vois pas comment je peux tester ma méthode checkIfValidElements, il ne retourne rien ou ne change rien. Quand j'exécute la couverture de code avec Maven, il me dit que le test unitaire couvre cette partie de ma classe.

La seule façon que je vois est de changer cette méthode pour retourner une valeur int ou bollean, comme ceci:

protected static int checkifValidElements(int arg1,  int arg2) {
    method1(arg1);
    method2(arg1);
    method3(arg1, arg2);
    method4(arg1, arg2);
    method5(arg1);
    method6(arg2);
    method7();
    return 0;
}

Avec cette méthode, je suis capable de faire une affirmation égale, mais il me semble que c'est futile de le faire. Le problème est que j'ai quelques classes qui sont conçues comme ça et son abaissement de ma couverture de test unitaire %.

45
demandé sur Michael Schmidt 2013-04-16 21:55:44

7 réponses

Je veux faire un test unitaire pour obtenir une couverture de code maximale

La couverture de Code ne devrait jamais être l'objectif d'écrire des tests unitaires. Vous devez écrire des tests unitaires pour prouver que votre code est correct, ou vous aider à le concevoir mieux, ou aider quelqu'un d'autre à comprendre ce que le code est censé faire.

Mais je ne vois pas comment je peux tester ma méthode checkIfValidElements, elle ne retourne rien ou ne change rien.

Eh bien, vous devriez probablement donner quelques tests, qui entre eux vérifient que toutes les 7 méthodes sont appelées de manière appropriée-à la fois avec un argument invalide et avec un argument valide, en vérifiant les résultats de ErrorFile à chaque fois.

Par exemple, supposons que quelqu'un a supprimé l'appel à:

method4(arg1, arg2);

... ou accidentellement changé l'ordre des arguments:

method4(arg2, arg1);

Comment remarqueriez-vous ces problèmes? Allez-y, et des tests de conception pour le prouver.

48
répondu Jon Skeet 2013-04-16 18:00:06

Si votre méthode n'a pas d'effets secondaires et ne renvoie rien, elle ne fait rien.

Si votre méthode effectue un calcul et renvoie le résultat de ce calcul, vous pouvez évidemment affirmer que le résultat retourné est correct.

Si votre code ne renvoie rien mais a des effets secondaires, vous pouvez appeler le code et ensuite affirmer que les effets secondaires corrects sont survenus. Quels sont les effets secondaires détermineront comment vous faites l' vérifier.

Dans votre exemple, vous appelez des méthodes statiques à partir de vos fonctions non renvoyantes, ce qui le rend difficile à moins que vous ne puissiez inspecter que le résultat de toutes ces méthodes statiques est correct. Une meilleure façon - d'un point de vue de test - est d'injecter des objets réels dans lesquels vous appelez des méthodes. Vous pouvez ensuite utiliser quelque chose comme EasyMock ou Mockito pour créer un objet fictif dans votre test unitaire, et injecter l'objet fictif dans la classe. L'objet simulé vous permet alors d'affirmer que le bon les fonctions ont été appelées, avec les valeurs correctes et dans le bon ordre.

Par exemple:

private ErrorFile errorFile;

public void setErrorFile(ErrorFile errorFile) {
    this.errorFile = errorFile;
}

private void method1(arg1) {
    if (arg1.indexOf("$") == -1) {

        //Add an error message 
        errorFile.addErrorMessage("There is a dollar sign in the specified parameter");
    }
}

, Puis dans votre test, vous pouvez écrire:

public void testMethod1() {
    ErrorFile errorFile = EasyMock.createMock(ErrorFile.class);
    errorFile.addErrorMessage("There is a dollar sign in the specified parameter");
    EasyMock.expectLastCall(errorFile);
    EasyMock.replay(errorFile);

    ClassToTest classToTest = new ClassToTest();
    classToTest.setErrorFile(errorFile);
    classToTest.method1("a$b");

    EasyMock.verify(errorFile); // This will fail the test if the required addErrorMessage call didn't happen
}
17
répondu Graham 2013-04-16 19:22:16

Vous pouvez toujours tester une méthode vide en affirmant qu'elle a eu l'effet secondaire approprié. Dans votre exemple method1, votre test unitaire peut ressembler à quelque chose comme:

public void checkIfValidElementsWithDollarSign() {
    checkIfValidElement("$",19);
    assert ErrorFile.errorMessages.contains("There is a dollar sign in the specified parameter");
}
4
répondu Jeff Storey 2013-04-16 18:00:12

Vous pouvez apprendre quelque chose appelé "moqueur". Vous pouvez l'utiliser, par exemple, pour vérifier si: - une fonction a été appelée - une fonction a été appelée x fois - une fonction a été appelée au moins x fois - une fonction a été appelée avec un ensemble spécifique de paramètres. Dans votre cas, par exemple, vous pouvez utiliser mocking pour vérifier que method3 a été appelée une fois avec tout ce que vous passez comme arg1 et arg2.

Jetez un oeil à ils: https://code.google.com/p/mockito/ https://code.google.com/p/powermock/

2
répondu Serban Stoenescu 2014-11-05 15:30:37

Je pense que vous devriez éviter d'écrire une méthode à effet secondaire. Renvoyez true ou false à partir de votre méthode et vous pouvez vérifier ces méthodes dans les tests unitaires.

1
répondu Garbage 2013-04-16 18:06:02

Si votre méthode est nulle et que vous voulez vérifier une exception, vous pouvez utiliser expected: https://weblogs.java.net/blog/johnsmart/archive/2009/09/27/testing-exceptions-junit-47

1
répondu Andreas Hartmann 2014-04-17 11:56:18

Si c'est possible dans votre cas, vous pouvez faire vos méthodes method1(arg1) ... method7() protégé au lieu de privé afin qu'ils puissent être accessibles à partir de la classe de test dans le même paquet. Ensuite, vous pouvez simplement tester toutes lesces méthodes séparément.

0
répondu martlin 2018-04-09 11:46:14