web-dev-qa-db-fra.com

Erreur Mockito avec une méthode qui renvoie facultatif <T>

J'ai une interface avec la méthode suivante

public interface IRemoteStore {

    <T> Optional<T> get(String cacheName, String key, String ... rest);

}

L'instance de la classe implémentant l'interface est appelée remoteStore.

Quand je me moque de ça avec mockito et utilise la méthode quand:

Mockito.when(remoteStore.get("a", "b")).thenReturn("lol");

Je reçois l'erreur:

Impossible de résoudre la méthode 'thenReturn (Java.lang.String)'

Je pensais que cela avait à voir avec le fait que get renvoie une instance de la classe Optional, j'ai donc essayé ceci:

Mockito.<Optional<String>>when(remoteStore.get("cache-name", "cache-key")).thenReturn
        (Optional.of("lol"));

Mais, je reçois cette erreur à la place:

lorsque (Facultatif '<' String '>') dans Mockito ne peut pas être appliqué à (Facultatif '<' Object '>').

La seule fois où cela a fonctionné était avec ceci:

String returnCacheValueString = "lol";
Optional<Object> returnCacheValue = Optional.of((Object) returnCacheValueString);
Mockito.<Optional<Object>>when(remotestore.get("cache-name", "cache-key")).thenReturn(returnCacheValue);

Mais ci-dessus renvoie une instance de '<' Object '>' facultatif et non de '<' String '> facultatif.

Pourquoi ne pourrais-je pas simplement retourner directement une instance de '<' String '>' facultative? Si je le pouvais, comment devrais-je m'y prendre?

22
Yu Lin Chen

Les mocks qui retournent s'attendent à ce que le type de retour corresponde au type de retour de l'objet simulé.

Voici l'erreur:

Mockito.when(remoteStore.get("a", "b")).thenReturn("lol");

"lol" N'est pas un Optional<String>, Il n'acceptera donc pas cela comme valeur de retour valide.

La raison pour laquelle cela a fonctionné quand vous l'avez fait

Optional<Object> returnCacheValue = Optional.of((Object) returnCacheValueString);
Mockito.<Optional<Object>>when(remotestore.get("cache-name", "cache-key")).thenReturn(returnCacheValue);

est dû au fait que returnCacheValue est un Optional.

C'est facile à corriger: il suffit de le remplacer par une Optional.of("lol") à la place.

Mockito.when(remoteStore.get("a", "b")).thenReturn(Optional.of("lol"));

Vous pouvez également supprimer les témoins types; le résultat ci-dessus sera inféré être Optional<String>.

31
Makoto

Je ne sais pas pourquoi vous voyez des erreurs, mais cela se compile/s'exécute sans erreur pour moi:

public class RemoteStoreTest {
    public interface IRemoteStore {
        <T> Optional<T> get(String cacheName, String key);
    }
    public static class RemoteStore implements IRemoteStore {
        @Override
        public <T> Optional<T> get(String cacheName, String key) {
            return Optional.empty();
        }
    }

    @Test
    public void testGet() {
        RemoteStore remoteStore = Mockito.mock(RemoteStore.class);

        Mockito.when( remoteStore.get("a", "b") ).thenReturn( Optional.of("lol") );
        Mockito.<Optional<Object>>when( remoteStore.get("b", "c") ).thenReturn( Optional.of("lol") );

        Optional<String> o1 = remoteStore.get("a", "b");
        Optional<Object> o2 = remoteStore.get("b", "c");

        Assert.assertEquals( "lol", o1.get() );
        Assert.assertEquals( "lol", o2.get() );
        Mockito.verify(remoteStore);
    }
}
1
Don Bottstein