英文:
Mockito 2 Mocks Returning Stream - No suitable method found
问题
以下是翻译好的内容:
我在实现中有一个带有以下签名的函数:
Class Foo {
Stream<? extends Bar> doSomething() { ... }
}
然而,在我的测试中,当我进行如下操作时:
when(foo.doSomething()).thenReturn(Stream.of(bar1, bar2));
我遇到了以下编译错误:
没有找到适合的 thenReturn(java.util.stream.Stream<Bar>) 方法
方法 org.mockito.stubbing.OngoingStubbing.thenReturn(java.util.stream.Stream<capture#1 of ? extends Bar>,java.util.stream.Stream<capture#1 of ? extends Bar>...) 不适用
(参数不匹配;推断变量 T 具有不兼容的界限
相等约束:capture#1 of ? extends Bar
下界:Bar)
不幸的是,使用 Stream.<? extends Foo>(bar1, bar2)
也不起作用。正在寻找解决方法。
谢谢!
编辑:
值得注意的是,当我使用 Mockito 1.10.x 时,这是可行的,但一旦我更新到 Mockito 2.28.x,它就不起作用了。
英文:
I have a function in the implementation with the signature
Class Foo {
Stream<? extends Bar> doSomething() { ... }
}
However, in my tests when I did something like
when(foo.doSomething()).thenReturn(Stream.of(bar1, bar2));
I got the following compilation error:
no suitable method found for thenReturn(java.util.stream.Stream<Bar>)
method org.mockito.stubbing.OngoingStubbing.thenReturn(java.util.stream.Stream<capture#1 of ? extends Bar>,java.util.stream.Stream<capture#1 of ? extends Bar>...) is not applicable
(argument mismatch; inference variable T has incompatible bounds
equality constraints: capture#1 of ? extends Bar
lower bounds: Bar)
Unfortunately, using Stream.<? extends Foo>(bar1, bar2)
didn't work either. Looking for a fix.
Thanks!
EDIT:
FYI this worked when I was using Mockito 1.10.x, it stopped working once i updated Mockito to 2.28.x
答案1
得分: 1
Solution
唯一可行的解决方法是使用 OngoingStubbing<T> thenAnswer(Answer<?> answer)
,它期望任何参数化类型 (Answer<?>
):
-
扩展的代码:
Stream<? extends Bar> stream = Stream.of(new Buzz(), new Buzz(), new Buzz());
Mockito.when(foo.doSomething()).thenAnswer(new Answer<Stream<? extends Bar>>() { @Override public Stream<? extends Bar> answer(InvocationOnMock invocation) { return stream; } });
-
简化版本:
Mockito.when(foo.doSomething()).thenAnswer(invocation -> stream);
Explanation
OngoingStubbing<T> thenReturn(T value)
方法在模拟 Stream<? extends Bar> doSomething()
方法时,期望输入是 Stream<? extends Bar>
类型。传递 Stream.of(bar1, bar2))
不能保证参数与相同的参数化类型匹配。
让 Buzz
扩展 Bar
:
Stream<? extends Bar> stream = Stream.of(new Buzz(), new Buzz(), new Buzz());
Mockito.when(foo.doSomething()).thenReturn(stream);
完全相同的问题也可以在以下代码中重现:
static class FluentFactory {
static <T> Fluent<T> fluent(T methodCall) { return new Fluent<>(); }
}
static class Fluent<T> {
Fluent<T> first(T t) { return new Fluent<>(); }
}
Stream<? extends Bar> stream = Stream.of(new Buzz(), new Buzz(), new Buzz());
FluentFactory.fluent(foo.doSomething()).first(stream);
错误:(xx, yy) java: 不兼容的类型: java.util.stream.Stream<capture#1 of ? extends com.mycompany.Foo> 无法转换为 java.util.stream.Stream<capture#2 of ? extends com.mycompany.Foo>
英文:
Solution
The only possible workaround is using OngoingStubbing<T> thenAnswer(Answer<?> answer)
which expects any parametrized type (Answer<?>
):
-
expanded:
Stream<? extends Bar> stream = Stream.of(new Buzz(), new Buzz(), new Buzz());
Mockito.when(foo.doSomething()).thenAnswer(new Answer<Stream<? extends Bar>>() { @Override public Stream<? extends Bar> answer(InvocationOnMock invocation) { return stream; } });
-
short version:
Mockito.when(foo.doSomething()).thenAnswer(invocation -> stream);
Explanation
The method OngoingStubbing<T> thenReturn(T value)
expects in case of mocking Stream<? extends Bar> doSomething()
method the Stream<? extends Bar>
type at the input. Passing Stream.of(bar1, bar2))
doesn't guarantee the parameters fit the same parametrized type.
Let Buzz
extend Bar
:
Stream<? extends Bar> stream = Stream.of(new Buzz(), new Buzz(), new Buzz());
Mockito.when(foo.doSomething()).thenReturn(stream);
The very same issue is reproducible with the following code:
static class FluentFactory {
static <T> Fluent<T> fluent(T methodCall) { return new Fluent<>(); }
}
static class Fluent<T> {
Fluent<T> first(T t) { return new Fluent<>(); }
}
Stream<? extends Bar> stream = Stream.of(new Buzz(), new Buzz(), new Buzz());
FluentFactory.fluent(foo.doSomething()).first(stream);
> Error:(xx, yy) java: incompatible types: java.util.stream.Stream<capture#1 of ? extends com.mycompany.Foo> cannot be converted to java.util.stream.Stream<capture#2 of ? extends com.mycompany.Foo>
答案2
得分: 0
一个解决方法是使用:
when(fooMock.doSomething())
.thenAnswer((Answer<Stream<? extends Bar>>) invocation -> Stream.of(bar1, bar2));
这不会导致编译或运行时错误。
英文:
A workaround to this, use:
when(fooMock.doSomething())
.thenAnswer((Answer<Stream<? extends Bar>>) invocation -> Stream.of(bar1, bar2));
This causes no compilation or runtime error.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论