You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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]]——这里有两个明显的类型问题:
    1. NoOpVal不是Done类型,右值的类型不符合要求
    2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 07:50:48