122

错误详情:

org.mockito.exceptions.misusing.WrongTypeOfReturnValue: 
Boolean cannot be returned by updateItemAttributesByJuId()
updateItemAttributesByJuId() should return ResultRich
This exception might occur in wrongly written multi-threaded tests.
Please refer to Mockito FAQ on limitations of concurrency testing.

我的代码:

@InjectMocks
protected ItemArrangeManager arrangeManagerSpy = spy(new ItemArrangeManagerImpl());
@Mock
protected JuItemWriteService juItemWriteService;

when(arrangeManagerSpy
    .updateItemAttributes(mapCaptor.capture(), eq(juId), eq(itemTO.getSellerId())))
    .thenReturn(false);

如您所见,我正在调用whenon updateItemAttributes(它确实返回 a boolean)而不是 on updateItemAttributesByJuId

  1. 为什么 Mockito 试图返回booleanfrom updateItemAttributesByJuId
  2. 如何纠正?
4

20 回答 20

252

根据https://groups.google.com/forum/?fromgroups#!topic/mockito/9WUvkhZUy90,您应该改写您的

when(bar.getFoo()).thenReturn(fooBar)

doReturn(fooBar).when(bar).getFoo()
于 2012-07-17T09:55:22.520 回答
43

出现类似错误消息的另一个原因是试图模拟一个final方法。不应尝试模拟最终方法(请参阅最终方法模拟)。

我还在多线程测试中遇到了错误。gna 的回答在这种情况下有效。

于 2013-12-02T12:54:09.820 回答
29

很感兴趣的问题。在我的情况下,当我尝试在类似的行上调试我的测试时导致了这个问题:

Boolean fooBar;
when(bar.getFoo()).thenReturn(fooBar);

重要的一点是测试在没有调试的情况下正确运行。

无论如何,当我用下面的代码片段替换上面的代码时,我能够毫无问题地调试问题行。

doReturn(fooBar).when(bar).getFoo();
于 2018-05-25T09:31:51.470 回答
9

对我来说,这意味着我正在运行这个:

a = Mockito.mock(SomeClass.class);
b = new RealClass();
when(b.method1(a)).thenReturn(c); 
// within this method1, it calls param1.method2() -- note, b is not a spy or mock

所以发生的事情是,mockito 正在检测a.method2()正在调用的那个,并告诉我我不能ca.method2()哪个错误返回。

修复:使用doReturn(c).when(b).method1(a)样式语法(而不是when(b.method1(a)).thenReturn(c);),这将帮助您更简洁快速地发现隐藏的错误。

或者在这种特殊情况下,在这样做之后它开始显示更准确的“NotAMockException”,我将其更改为不再尝试从非模拟对象设置返回值。

于 2018-05-09T16:48:46.970 回答
6

我最近遇到了这个问题。问题是我试图模拟的方法没有访问修饰符。添加公众解决了这个问题。

于 2014-09-18T19:29:48.083 回答
5

我有这个错误是因为在我的测试中我有两个期望,一个是模拟类型,一个是具体类型

MyClass cls = new MyClass();
MyClass cls2 = Mockito.mock(Myclass.class);
when(foo.bar(cls)).thenReturn(); // cls is not actually a mock
when(foo.baz(cls2)).thenReturn();

我通过将 cls 更改为模拟来修复它

于 2017-07-12T08:23:22.333 回答
4

在我的情况下,问题是由于尝试模拟静态方法而忘记调用mockStatic类引起的。我也忘了把课程包括在@PrepareForTest()

于 2017-06-14T16:21:56.060 回答
3

就我而言,我同时使用@RunWith(MockitoJUnitRunner.class)MockitoAnnotations.initMocks(this)。当我删除它时MockitoAnnotations.initMocks(this),它工作正常。

于 2019-04-23T18:42:03.607 回答
2

如果您使用注解,可能需要使用@Mock 而不是@InjectMocks。因为@InjectMocks 作为@Spy 和@Mock 一起工作。@Spy 会跟踪最近执行的方法,您可能会觉得返回/替换了不正确的数据。

于 2014-01-08T17:16:32.440 回答
2

TL;DR如果您的测试中的某些参数是null,请务必使用isNull()而不是模拟参数调用anyXXX()


从 Spring boot 1.5.x 升级到 2.1.x 时出现此错误。Spring boot 附带了自己的 Mockito,现在也升级到 2.x(参见Spring boot 2.1.2 的依赖项

Mockito 更改了anyXXX()方法的行为,其中XXXis StringLong等。这是 javadoc 的anyLong()

从 Mockito 2.1.0 开始,只允许 valued Long,因此 null不再是有效值 由于原始包装器可以为空,建议匹配 null包装器的 API 是#isNull(). 我们认为这种变化将使测试工具比 Mockito 1.x 更安全。

我建议你调试到你的模拟将被调用并检查,是否至少一个参数是null. 在这种情况下,请确保您使用isNull()而不是 eg 来准备模拟anyLong()

所以这:

when(MockedClass.method(anyString());

变成:

when(MockedClass.method(isNull());
于 2020-07-15T17:44:23.210 回答
1

我最近在模拟 Kotlin 数据类中的函数时遇到了这个问题。由于某种未知原因,我的一次测试运行最终处于冻结状态。当我再次运行测试时,我之前通过的一些测试开始失败并出现WrongTypeOfReturnValue异常。

我确保我org.mockito:mockito-inline用来避免最终课程的问题(Arvidaa 提到),但问题仍然存在。为我解决的问题是终止进程并重新启动 Android Studio。这终止了我的冻结测试运行,并且以下测试运行顺利通过。

于 2018-10-19T11:33:07.957 回答
1

在我的例子中,bean 已经使用@Autowired注释而不是@MockBean进行了初始化

因此,以这种方式模拟 DAO 和服务会引发此类异常

于 2019-11-07T18:26:06.713 回答
1

在我的情况下,或者更确切地说是Android项目的仪器测试,
我只需要删除build目录(强制重建)。

也许一个错误的原因太多了!
(他们应该已经解决了这个问题)。

但我希望这对某人有帮助
d= (◕‿↼ )

于 2021-03-24T16:29:19.893 回答
1

对我来说,问题是在共享模拟上进行存根/验证的多线程测试。它导致随机抛出WrongTypeOfReturnValue异常。

这不是使用 Mockito 正确编写的测试。不应从多个线程访问模拟。

解决方案是为每个测试制作本地模拟。

于 2020-06-11T11:24:38.063 回答
1

我遇到了这个问题WrongTypeOfReturnValue,因为我模拟了一个返回 a 的方法java.util.Optional;com.google.common.base.Optional;因为我的格式化程序会自动添加缺少的导入。

Mockito 只是在说“method something() 应该返回 Optional”...

于 2019-10-01T09:54:14.377 回答
1

错误:

org.mockito.exceptions.misusing.WrongTypeOfReturnValue:
String 不能由 size() 返回
size() 应该返回 int
***
如果您不确定为什么会出现上述错误,请继续阅读。
由于上述语法的性质,可能会出现以下问题,因为:
1. 此异常可能发生在错误编写的多线程
测试中。
有关并发测试的限制,请参阅 Mockito 常见问题解答。
2. 使用 when(spy.foo()).then() 语法对 spy 进行存根。 使用 doReturn|Throw() 系列方法来
存根间谍更安全。
更多关于
Mockito.spy() 方法的 javadocs。

实际代码:

@RunWith(PowerMockRunner.class)
@PrepareForTest({ Object.class, ByteString.class})

@Mock
private ByteString mockByteString;

String testData = “dsfgdshf”;
PowerMockito.when(mockByteString.toStringUtf8()).thenReturn(testData); 
// throws above given exception

解决此问题的解决方案:

第一次删除注释“@Mock”。

private ByteString mockByteString;

第二次添加PowerMockito.mock

mockByteString = PowerMockito.mock(ByteString.class);
于 2018-05-04T21:49:35.200 回答
1

在要模拟的 bean 上缺少 @MockBean

于 2019-02-18T03:26:22.327 回答
0

我正在使用 Scala,并且收到了这条消息,我错误地在两个Objects 之间共享了一个 Mock。因此,请确保您的测试彼此独立。并行测试执行显然会产生一些不稳定的情况,因为 Scala 中的对象是单例组合。

于 2021-02-11T15:12:21.717 回答
0

就我而言,事实证明模拟对象的类型实际上是一个抽象接口,将类型更改为某个实现类后问题得到解决,

改变

@Mock
private Proxy proxy;

@Mock
private ProxyImpl proxy;
于 2021-11-03T04:18:32.877 回答
-1

这是我的情况:

//given
ObjectA a = new ObjectA();
ObjectB b = mock(ObjectB.class);
when(b.call()).thenReturn(a);

Target target = spy(new Target());
doReturn(b).when(target).method1();

//when
String result = target.method2();

然后我得到这个错误:

org.mockito.exceptions.misusing.WrongTypeOfReturnValue: 
ObjectB$$EnhancerByMockitoWithCGLIB$$2eaf7d1d cannot be returned by method2()
method2() should return String

猜一下?

问题是 Target.method1() 是一个静态方法。Mockito 完全警告我另一件事。

于 2018-12-03T21:14:45.987 回答