Mockito单步调试失败求助:Debug运行正常单步报错
问题描述
在Windows环境下使用Java+Mockito编写测试时,编写了如下代码:
when(mongoTemplate.findAndModify(any(Query.class), any(Update.class), any(FindAndModifyOptions.class), eq(Task.class))) .thenReturn(t1) .thenReturn(t2);
Debug模式直接运行正常,但在when语句处打断点并单步调试时出现报错。IntelliJ中报错信息如下:
org.mockito.exceptions.misusing.WrongTypeOfReturnValue:
Task cannot be returned by toString()
toString() should return StringIf you're unsure why you're getting above error read on.
Due to the nature of the syntax above problem might occur because:
- This exception might occur in wrongly written multi-threaded tests.
Please refer to Mockito FAQ on limitations of concurrency testing.- A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies -
- with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.
推测是IntelliJ单步调试时调用了toString()方法导致的,疑问:Mockito是否需要在OngoingStubbing中处理toString()的回退?
问题分析与解决办法
- 报错根源:确实是IntelliJ调试行为引发的问题。当在
when语句处断点单步调试时,IDE会自动调用OngoingStubbing实例的toString()方法来展示调试信息。而你给该Stub设置的返回值是Task类型,但toString()要求返回String,Mockito因此抛出类型不匹配的错误。 - 解决方式:
- 改用
doReturn语法替代when...thenReturn,这种语法不会触发真实方法调用(包括调试时的toString()),代码示例:doReturn(t1).doReturn(t2).when(mongoTemplate).findAndModify(any(Query.class), any(Update.class), any(FindAndModifyOptions.class), eq(Task.class)); - 调试时避开在
when语句的返回值链上断点,直接跳过when语句的单步调试,待Stub设置完成后再调试后续逻辑。
- 改用
- 关于
toString()回退的疑问:Mockito不需要专门在OngoingStubbing中处理toString()的回退。这个问题本质是调试工具的行为干扰了Mockito的Stub逻辑,而非Mockito的设计缺陷。when...thenReturn语法基于代理对象的方法调用拦截,当IDE调用toString()时,Mockito会误将其当作需要Stub的方法,用你设置的Task返回值去匹配toString()的返回类型,进而触发报错。
内容的提问来源于stack exchange,提问作者Richard Keene
相关产品推荐
相关产品推荐

