Java 返回 Optional<T> 的方法的 Mockito 错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30946167/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 10:24:24  来源:igfitidea点击:

Mockito error with method that returns Optional<T>

javamockitooptional

提问by Yu Lin Chen

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.

实现该接口的类的实例称为 remoteStore。

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

当我用 mockito 模拟它并在以下情况下使用该方法时:

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

I get the error:

我收到错误:

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

无法解析方法“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:

我认为这与 get 返回 Optional 类的实例有关,所以我尝试了这个:

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'>').

当 Mockito 中的 (Optional '<'String'>') 不能应用于 (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'>.

但上面返回一个可选的'<'Object'>'而不是可选的'<'String'>的实例。

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

为什么我不能直接返回 Optional '<'String'>' 的实例?如果可以,我该怎么做?

采纳答案by Makoto

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.

"lol"不是Optional<String>,所以它不会接受它作为有效的返回值。

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 returnCacheValuebeing an Optional.

是由于returnCacheValueOptional.

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

这很容易解决:只需将其更改为 an 即可Optional.of("lol")

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>.

您也可以取消类型见证人。上面的结果将被推断为Optional<String>

回答by Don Bottstein

Not sure why you are seeing errors, but this compiles/runs error-free for me:

不知道为什么你会看到错误,但这对我来说编译/运行没有错误:

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);
    }
}