Mockito2中doReturn重载定义引用歧义编译错误求助
解决Mockito 2.18.0中doReturn的重载歧义问题
为什么歧义并非一直存在?
这个问题的核心是Scala与Java重载方法的类型推断差异,再加上Mockito的API版本变更:
- 在更早的Mockito版本里,
doReturn可能只提供了可变参数版本(doReturn(Object, Object...)),没有单参数的重载方法,所以传入单个参数时完全不会有歧义。 - 从Mockito 2.18.0开始,官方新增了单参数的
doReturn(Object)重载。Java编译器遇到这种场景会自动优先选择单参数版本,但Scala的类型检查逻辑更严格——它认为单个参数既可以匹配单参数方法,也能作为可变参数的第一个元素(剩余参数为空数组),因此判定两个方法都符合调用条件,最终抛出“模糊引用”的编译错误。
如何修改代码使其编译通过?
有几种简单的方式可以消除歧义,按推荐程度排序:
1. 显式指定调用单参数版本
通过将参数显式转换为AnyRef(对应Java的Object),引导编译器明确选择单参数的doReturn:
doReturn(Future.Unit: AnyRef).when(f.adapterSpy).myFunction(userData, Some(offerId), Always)
2. 显式传递可变参数的空数组
告诉编译器使用可变参数版本,传入空数组作为后续参数:
doReturn(Future.Unit, Array.empty[Object]: _*).when(f.adapterSpy).myFunction(userData, Some(offerId), Always)
这里的: _*是Scala中把数组展开为可变参数的语法。
3. 切换到thenReturn语法(如果适用)
如果myFunction不是void方法,且调用它不会触发真实逻辑导致空指针或副作用,可以改用更简洁的thenReturn:
when(f.adapterSpy.myFunction(userData, Some(offerId), Always)).thenReturn(Future.Unit)
不过如果你的场景必须用doReturn(比如测试void方法、避免执行真实方法逻辑),还是前两种方法更适配。
内容的提问来源于stack exchange,提问作者tjarvstrand
相关产品推荐
相关产品推荐

