Yu Lin Chen Yu Lin Chen - 3 months ago 78
Java Question

Mockito error with method that returns Optional<T>

I have an interface with the following method

public interface IRemoteStore {

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

}


The instance of the class implementing the interface is called remoteStore.

When I mock this with mockito and use the method when:

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


I get the error:


Cannot resolved the method 'thenReturn(java.lang.String)'


I thought it has to do with the fact that get returns an instance of the Optional class so I tried this:

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


But, I get this error instead:


when (Optional '<'String'>') in Mockito cannot be applied to (Optional'<'Object'>').


The only time it worked was with this:

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


But above returns an instance of Optional '<'Object'>' and not Optional '<'String'>.

Why couldn't I just return an instance of Optional '<'String'>' directly? If I could, how should I go about doing that?

Answer

Mocks that return have the expectation that the return type matches the mocked object's return type.

Here's the mistake:

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

"lol" isn't an Optional<String>, so it won't accept that as a valid return value.

The reason it worked when you did

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

is due to returnCacheValue being an Optional.

This is easy to fix: just change it to an Optional.of("lol") instead.

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

You can also do away with the type witnesses as well; the result above will be inferred to be Optional<String>.

Comments