1
votes

Mocking and Handling Map.Entry lorsqu'il est renvoyé par un appel de méthode

Résumé: Je ne sais pas comment gérer un seul "Map.Entry" lorsqu'il est renvoyé par un appel de méthode. Dans mon cas particulier, je dois me moquer de cela (en utilisant actuellement mockito) mais ma question porte autant sur la manière de traiter "Map.Entry" que sur la moquerie ... apprécié.

============================

J'ai une méthode comme la suivante. Je dois créer une entité correspondante (une Map.Entry que je suppose) pour que la maquette revienne lorsque la méthode est appelée. Je ne sais pas comment créer une seule Map.Entry. J'ai retracé les appels jusqu'à l'appel SQL vers la base de données, mais je ne peux trouver qu'un point où l'objet retourné est converti en Map.Entry.

Aucune indication sur la façon de construire une telle chose. J'ai besoin d'aide pour construire un seul "Map.Entry" qui peut être retourné par le simulacre.

assertTrue(The Key == SomeDate)
assertTrue(The Value == True)

Voici une ligne qui créerait l'objet simulé pour moi. Pour simplifier, supposons que la méthode ci-dessus soit dans la classe "Foo".

when(foo.getLastModifiedGid(any())).thenReturn(the Map.Entry I don't know how to make yet);

Ensuite, j'aurais besoin de quelque chose comme ça pour dire que lorsque la méthode est appelée (comme un simulacre ), il doit renvoyer le "Map.Entry" que j'ai besoin de construire.

Foo foo = mock(Foo.class);

Enfin, j'ai besoin d'affirmer quelque chose de testable à propos de Map.Entry qui est retourné. Je suis prêt à vérifier la clé et la valeur dans l'assert - rien de plus sophistiqué que cela n'est requis - encore une fois, je ne suis pas sûr de savoir comment j'accéderais à cela en tant que Map.Entry ...

 public Map.Entry<Date,Boolean> getLastModified(SomeClass someClass)
    throws Exception
    {
        return clusterViewDataProvider.getClusterModified(someClass);
    }

Si je n'ai pas été clair sur quoi que ce soit, veuillez commenter et je clarifierai. Gratzi.


5 commentaires

Accédez au javadoc de Map.Entry: docs .oracle.com / javase / 8 / docs / api / java / util / Map.Entry.html . Regardez la liste des classes d'implémentation. Choisissez celui que vous préférez. Créez une instance de cette classe.


Comment placer une Map.Entry dans un HashMap? Comment accepter la valeur de retour de cette méthode? Peu importe l'instance de la classe d'implémentation que j'utilise probablement, mais je ne sais pas à quoi ressemblerait le code et la lecture de la documentation n'est pas très utile dans ce cas. Un échantillon de code serait apprécié. Ce lien suggère que ce n'est pas simple ... stackoverflow.com/questions/39441096/...


when (foo.getLastModifiedGid (any ())). thenReturn (new AbstractMap.SimpleEntry (someKey, someValue))


@JBNizet Merci beaucoup!


J'ai également trouvé cette approche pour créer mon "objet à renvoyer par un faux" Map.Entry me = new AbstractMap.SimpleImmutableEntry <> (new Date (), Boolean.TRUE);


3 Réponses :


2
votes

Vous pouvez implémenter votre propre entrée

when(foo.getLastModifiedGid(any())).thenReturn(new DummyEntry(...))

Et la renvoyer ensuite dans votre maquette.

class DummyEntry<K,V> implements Map.Entry<K, V> {

        K key;
        V value;

        public DummyEntry(K key, V value) {
            this.key = key;
            this.value = value;
        }

        @Override
        public K getKey() {
            return key;
        }

        @Override
        public V getValue() {
            return value;
        }

        @Override
        public V setValue(V value) {
            this.value = value;
            return value;
        }
    }


0 commentaires

2
votes

La création de votre propre classe Entry personnalisée nécessite beaucoup d'implémentation de code supplémentaire uniquement pour le cas des tests .

Cela devrait être un drapeau rouge pour la conception de tests, car il est probable que vous compliquiez le problème beaucoup plus qu'il ne le devrait.

Au lieu de cela, pourquoi ne pas créer une carte réelle et avoir la carte fait le travail?

    //define your expected response element
    Date foo = ...;
    Boolean bar = ...;

    //instantiate map
    Map<Date,Boolean> dummyMap = new HashMap<>();
    dummyMap.put(foo, bar);

    //fetch an actual working copy from a functional map
    Map.Entry<Date, Boolean> baz = dummyMap.entrySet().stream().findFirst().get();

    //mock away
    when(foo.getLastModifiedGid(any())).thenReturn(baz);

Je ne sais pas pourquoi vous affirmeriez quelque chose concernant l'entrée elle-même. Si vous le définissez, ce devrait être le vôtre. Si votre méthode en cours de test la modifie, testez les résultats, et non l'objet prédéfini que vous lui avez fourni.


1 commentaires

Je suis d'accord sur la question du test de l'entrée - dans ce cas, je me moque d'un "hit" sur une base de données - je ne veux pas frapper la base de données dans un test unitaire, comme je suis sûr que vous serez d'accord. . Ce "hit" à la base de données est de plusieurs niveaux de profondeur et je suppose que ce que je fais est de "tester" que rien entre les deux ne mute ce que cet appel de niveau profond retourne ... meilleure utilisation de mon temps, mais les règles d'entreprise imposent une couverture de code élevée - et donc je les écris ...



3
votes

Il n'est pas nécessaire de créer votre propre implémentation de Map.Entry . Vous pouvez utiliser l'une des implémentations existantes comme AbstractMap.SimpleEntry :

Map.Entry<Date, Boolean> entry =  new AbstractMap.SimpleImmutableEntry<>(date, value);

ou AbstractMap.SimpleImmutableEntry : p >

Date date = new Date();
boolean value = true;

Map.Entry<Date, Boolean> entry =  new AbstractMap.SimpleEntry<>(date, value);
when(foo.getLastModifiedGid(any())).thenReturn(entry);

En remarque, les classes de date de java.util sont obesolètes et les classes de java.time doivent être utilisées pour Java 8+. Plus précisément, java.util.Date est remplacé par java.time.Instant .


2 commentaires

Bon point sur java.time . Et même pour Java 6 et Java 7, il est préférable d'utiliser la bibliothèque back-port, ThreeTen- Backport , que d'utiliser les terribles classes de date-heure héritées telles que Date .


D'accord - Je me moque du code hérité pour les tests unitaires qui auraient dû être écrits il y a longtemps - donc l'utilisation de Date ...