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

Scala中Mock参数为新实例的方法报错,求解决办法

解决Mockito匹配值类方法的异常问题

看起来你遇到的问题主要有两个关键点:参数名不匹配和值类(AnyVal)的Mockito匹配器兼容问题,咱们一步步来解决:

首先,先揪出最直接的错误:你在mock时写了service = any[Client],但原方法的第二个参数是Client类型,参数名应该是client(因为Scala中如果方法定义没显式写参数名,默认是小写的类型名)。这个参数名不匹配会导致Mockito无法正确绑定参数位置,直接触发InvalidUseOfMatchersException,这是你当前报错的直接原因。

接下来处理值类的匹配问题:因为Token、Client、Scope都是继承AnyVal的case class,Scala编译时会对这类值类做优化(运行时会拆箱为底层的String),而原生Mockito的any[Token]这类类型匹配器无法很好地识别这种优化后的类型,所以即使参数名改对了,可能还是会有问题。这里给你几个可行的解决方案:

方案1:使用argThat匹配任意值类实例

通过argThat自定义匹配逻辑,只要是对应类型的实例就匹配:

import org.mockito.ArgumentMatchers.argThat

when(mockService
  .delete(
    token = argThat(_: Token => true),
    client = argThat(_: Client => true),
    scope = argThat(_: Scope => true)
  )
).thenReturn(1.toFut)

方案2:结合值类构造函数和字符串匹配器

因为你的值类都是包装String的,所以可以直接用anyString()生成任意字符串,再包装成对应值类:

import org.mockito.ArgumentMatchers.anyString

when(mockService
  .delete(
    token = Token(anyString()),
    client = Client(anyString()),
    scope = Scope(anyString())
  )
).thenReturn(1.toFut)

方案3:改用mockito-scala(推荐)

如果你还在使用原生Mockito,强烈建议切换到mockito-scala,它对Scala的特性(包括值类、case class等)有更好的支持,不需要额外处理就能直接用any[Token]:

import org.mockito.MockitoSugar._

// 直接用位置参数更稳妥,避免参数名问题
when(mockService.delete(any[Token], any[Client], any[Scope]))
  .thenReturn(1.toFut)

最后给个小建议:mock方法时尽量用位置参数代替命名参数,因为Scala默认编译选项会丢弃参数名信息,命名参数在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:52:17