Mockito单步执行失败



好吧,这很奇怪。Mockito,Java,在windows上。

when(mongoTemplate.findAndModify(any(Query.class), any(Update.class), any(FindAndModifyOptions.class), eq(Task.class)))
.thenReturn(t1)
.thenReturn(t2);

现在,如果我在调试模式下运行它,它可以正常工作。但如果我把一个转折点放在什么时候,一步就失败了。

IntelliJ中的错误是

org.mockito.exceptions.misusing.WrongTypeOfReturnValue: 
Task cannot be returned by toString()
toString() should return String
***
If you're unsure why you're getting above error read on.
Due to the nature of the syntax above problem might occur because:
1. This exception *might* occur in wrongly written multi-threaded tests.
Please refer to Mockito FAQ on limitations of concurrency testing. 
2. 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上抓住并回退到String?

此行为是有意的,必须是,否则toString将不可构建或不可用。

Mockito存根通过副作用和代理进行工作。对于像您这样的电话:

when(mongoTemplate.findAndModify(any(Query.class), any(Update.class), any(FindAndModifyOptions.class), eq(Task.class)))
.thenReturn(t1)
.thenReturn(t2);

Mockito利用了可预测的Java执行顺序,它按顺序评估方法参数,然后方法调用自己,因此它看到:

  1. any(Query.class):1参数匹配器堆栈上的匹配器,返回null
  2. any(Update.class):堆栈上有2个匹配器,返回null
  3. any(FindAndModifyOptions.class):堆栈上有3个匹配器,返回null
  4. eq(Task.class):堆栈上有4个匹配器,返回null
  5. findAndModify(null, null, null, null):返回findAndModify返回的内容,findAndModify现在是最近的调用
  6. when:我们现在用四个参数匹配器来模拟最近的调用findAndModify,重置堆栈
  7. thenReturn(t1):在when返回的存根链上添加一个操作
  8. thenReturn(t2):在when返回的存根链上添加一个操作

如果您的IDE在步骤5和步骤6之间调用toString,那么Mockito将假设您之前有意调用findAndModify(null, null, null, null),现在正试图存根toString。由于您试图返回t1,这意味着Mockito将告诉您,您的toString()存根需要一个String,但收到一个Task。

尽管这很烦人,但可以说,与Mockito拒绝存根toString()或您完全无法在mock上调用toString()相比,它没有那么烦人。

最新更新