9
votes

Comment tester des méthodes anonymes avec Junit ou Makeito?

Je classe simple mais avec bloc anonyme de code. Je dois couvrir cette classe avec des tests

@RunWith(MockitoJUnitRunner.class)
public class CleanerTaskTest {

    final static int CLEANER_DELAY = 5;

    @Mock
    DataWarehouseMessageDao dao;

    @Mock
    TransactionTemplate template;

    CleanerTask cleanerTask;

    @Before
    public void setUp() throws Exception {
        cleanerTask = new CleanerTask(dao, CLEANER_DELAY, template);
    }

    @Test
    public void successfulScenario() {
        try {
            cleanerTask.clean();
            verify(template, times(1)).execute(isA(TransactionCallback.class));
            //that verify was not triggered    
            //verify(dao, times(1)).deleteAllByStatusAndDate(anyInt(), isA(Date.class));
        } catch (Exception e) {
            e.printStackTrace();
            fail("No exceptions must occur");
        }
    }
}


0 commentaires

3 Réponses :


14
votes

Pourquoi ça ne marche pas

Eh bien, votre problème ici est que transactiontemplate dans votre test est une simule. En tant que tel, il a la même interface que transactiontemplate mais ne sait pas comment se comporter. Vous êtes responsable de sa mise en œuvre - c'est tout le point de moqueur. Vous appelez explicitement template.execute () dans votre code et c'est pourquoi votre première vérification passe. Mais que exécuter () n'est pas celui du ressort (ou plus précisément dans votre test n'est pas une instance de transactiontemplaire , C'est SEULEMENT UN MOCK DE THI) - C'est bien, disons que c'est "vide" comme il est invoqué sur une maquette et que vous n'avez pas dit la maquette comment appeler exécutant () dessus devrait se comporter.

Comment je vais le réparer

Dans des cas comme celui-ci, je serais vraiment vous décourager de ces tests de l'unité, car vous testez implémentation ici. Ce que vous devriez tester, au moins en fonction de moi, est la fonctionnalité signifiant Signification donnée certaines conditions, quand quelque chose se passe alors Certains résultat devraient se produire. Cela nécessiterait de modifier cela sur un test d'intégration (en utilisant des moyens de dire dbunit ou autre chose) et affirmez si vous avez réellement supprimé ce que vous étiez censé supprimer. Je veux dire qu'est-ce que vous vous souciez vraiment de savoir que certaines méthodes ont été invoquées ou que quelque chose que vous espérais réellement arrivé?

Comment vous pouvez, mais IMHO ne devrait pas, corrigez-le.

mais si vous vraiment voulez tester ce morceau de code anonyme, je l'extraire tout simplement (toute la classe anonyme) à une classe distincte et écrivez un test d'unité juste pour cette nouvelle classe et plus Précisément pour c'est dointransaction () méthode. Dans ce cas, vous le créeriez à l'aide de Nouveau , définissant un simule DatawareHousemessagedao et simplement votre vérifie () . .


1 commentaires

Merci de répondre. J'ai résolu ce problème en ajoutant une annotation @TransAderal à ma méthode, donc pas besoin de créer des méthodes anonymes plus et que la création de test est devenue plus facile.



2
votes

Vous ne devriez pas changer votre code, c'est vrai. Dans votre test de l'unité, au lieu de la vérification ISA, vous devez utiliser ArgumentCaptorCaptor pour capturer le paramètre passé, validez cette instance est le type de transactionCallback et invoquer la méthode DOINTRANSAction à ce sujet. Vous seriez donc en mesure de vérifier que DAO a été invoqué avec le paramètre attendu (conseils que vous pouvez utiliser EQ Matchers pour vérifier la valeur exacte).

C'est vrai que dans ce test, vous allez tester deux choses à la fois, mais ce n'est qu'à cause de votre mise en œuvre et je ne dis pas que c'est faux. Créer de nouvelles instances avec une certaine logique d'entreprise augmente toujours le couplage dans votre code, mais cela ne signifie pas que nous ne devrions pas utiliser les capacités linguistiques pour le faire.


0 commentaires

0
votes

Voici une autre façon de traiter avec transactiontemplate (Java 8 +): xxx

Cette solution exécutera le code dans cette fausse transaction et vous pouvez vérifier la réponse ensuite.


0 commentaires