【问题标题】:Mockito error with method that returns Optional<T>返回 Optional<T> 的方法的 Mockito 错误
【发布时间】:2015-09-05 21:51:00
【问题描述】:

我有如下方法的接口

public interface IRemoteStore {

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

}

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

当我用 mockito 模拟这个并使用该方法时:

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

我得到错误:

无法解析方法'thenReturn(java.lang.String)'

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

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

但是,我得到了这个错误:

当 Mockito 中的 (Optional '') 不能应用于 (Optional'')。

它唯一的工作是用这个:

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

但上面返回一个可选的''的实例,而不是可选的'。

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

【问题讨论】:

  • 你不是在第一个代码块中缺少一个括号吗?
  • 另外仅供参考,不要将java.util.Optionalcom.google.common.base.Optional 混淆,因为后者需要在此处导入。

标签: java mockito optional


【解决方案1】:

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

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

【讨论】:

  • 嗨,唐,感谢您的回复。这让我意识到我的 IDE 将项目语言级别设置为 java 7,而不是 java 8。但我使用的是来自 Guava 的 Optional,而不是 Java 8,但这是一个不同的问题。谢谢。
  • 解释为什么它起作用比说它起作用要好。 OP 可能不是唯一遇到此问题的人;其他人将来可能会进来并有类似的问题。
【解决方案2】:

返回的 Mocks 期望返回类型与被模拟对象的返回类型匹配。

这是错误:

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

"lol" 不是 Optional&lt;String&gt;,因此它不会接受它作为有效的返回值。

你这样做的原因

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

因为returnCacheValueOptional

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

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

您也可以取消类型见证。上面的结果将被推断为Optional&lt;String&gt;

【讨论】:

  • 您好,感谢您的回复。是的,我意识到了错误并改变了它。问题是我没有将项目语言级别设置为 java 8。
  • 阅读您的问题后,我不会知道这一点。 Optional 是 Google Guava 中的一个类 - 一个非常流行的第三方库 - 它与 Java 7 兼容。
  • 这太棒了!希望我能给更多的赞成票。 thenReturn(Optional.of("lol"));
  • @Yu Lin Chen - 你能在这里指导我吗:stackoverflow.com/questions/56135373/…
  • 谢谢。没关系,但我不明白为什么我们应该在 thenReturn 中使用 Optional.of??
猜你喜欢
  • 2019-07-20
  • 1970-01-01
  • 1970-01-01
  • 2019-11-03
  • 1970-01-01
  • 2017-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多