Mockito中thenReturn重载报错如何解决?附Scala代码场景
问题分析与解决
1. 为什么thenReturn有多重载选项?
这是Mockito的故意设计,目的是支持「连续调用返回不同结果」的测试场景。两个重载的作用分别是:
- 单参数版本:只传入一个返回值,不管调用多少次mock方法都返回这个值
- 多参数(可变参数)版本:可以传入多个返回值,第一次调用返回第一个值,第二次返回第二个,以此类推,适合测试状态变化或重试逻辑这类场景
举个实际使用的例子:
when(mockService.someMethod()) .thenReturn(Future.successful(Right(Done)), Future.failed(new Exception("retry failed")))
第一次调用someMethod返回成功的Future,第二次就返回失败的结果,很适合模拟重试失败的测试场景。
2. 如何解决你的类型不匹配报错?
你的核心问题是返回值类型和mock方法的签名完全不兼容,拆解一下问题点:
saveToken方法的返回类型是Future[EitherErrorsOr[Done]],也就是Future[Either[Errors, Done]]- 你写的
Right(NoOpVal).toFut返回的是Future[Right[Nothing, NoOp]]——这里有两个明显的类型问题:NoOpVal不是Done类型,右值的类型不符合要求Right是Either的子类,但Scala不会自动把Right向上转型为Either,加上泛型约束后,两个类型完全无法匹配
修正方案
你需要把返回值明确转换成EitherErrorsOr[Done]类型,并且用Done的合法实例代替NoOpVal(如果NoOpVal是你模拟的Done实现,要确保它继承/实现了Done)。
假设你有一个测试用的Done实例(比如Done是单例,或者你创建了测试实例),可以用以下两种方式修正:
// 先准备一个合法的 Done 实例 val testDone: Done = Done // 如果是单例直接用,或者 new Done(...) 按需创建 // 方式1:显式指定 Either 类型 when(mockService.saveToken(any(), any(), any(), any(), any())) .thenReturn( (Right(testDone): EitherErrorsOr[Done]).toFut ) // 方式2:用 Either 的 right 方法明确构造目标类型 when(mockService.saveToken(any(), any(), any(), any(), any())) .thenReturn( Either.right[Errors](testDone).toFut )
如果你的toFut方法本质和Future.successful(...)一样,也可以直接写:
when(mockService.saveToken(any(), any(), any(), any(), any())) .thenReturn( Future.successful(Right(testDone): EitherErrorsOr[Done]) )
这样就能保证返回值的类型和mock方法的签名完全匹配,编译器就不会再抛出类型不匹配的报错了。
内容的提问来源于stack exchange,提问作者Saturnian
相关产品推荐
相关产品推荐

