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

ScalaMock如何mock包含重载柯里化传名参数方法的trait?

ScalaMock 5.1 重载带传名参数方法的正确Mock写法

Scala 2.13 + ScalaMock 5.1 完全支持mock该trait中的两个重载bar方法,你之前的写法报错核心是两个问题:

  1. 没有显式给方法指定签名,导致编译器无法区分两个重载的bar方法
  2. 错误将传名参数类型=> Double等同于无参函数类型() => Double,且多余的下划线语法使用错误

各报错原因说明

  • 第一种写法报错:末尾多余的_相当于尝试将已经完成参数占位的方法再转为函数,不符合语法要求
  • 第二、第三种写法报错:你将第二个参数列表的传名参数=> Double错误声明为() => Double,二者是Scala中完全不同的类型,触发类型不匹配
  • 第四种写法报错:没有给方法显式声明类型,编译器无法从上下文中判断你要mock的是单参数还是双参数列表的重载方法,因此报无法解析重载方法

正确Mock写法

1. Mock双参数列表带传名参数的bar方法

两种常用写法,均需先显式指定方法签名消除重载歧义:

expects风格写法

val mockFoo = mock[Foo]
// 显式声明方法签名,帮编译器定位到目标重载方法
val targetBar: (Int, => Double) => Double = mockFoo.bar(_: Int)(_: Double)
// 匹配入参第一个为1,第二个传名参数任意,返回2.0
targetBar.expects(1, *).returns(2.0)

when风格写法

val mockFoo = mock[Foo]
val targetBar: Int => (=> Double) => Double = mockFoo.bar
when(targetBar(1)(*)).thenReturn(2.0)

2. Mock单参数列表的bar方法

同理显式指定签名即可:

val mockFoo = mock[Foo]
val singleBar: Double => Double = mockFoo.bar
// 匹配入参为1.0时返回3.0
singleBar.expects(1.0).returns(3.0)

验证效果

调用mock后的方法符合预期,且传名参数不会实际执行:

val res1 = mockFoo.bar(1) {
  println("这段代码不会执行")
  100.0
}
// res1 = 2.0

val res2 = mockFoo.bar(1.0)
// res2 = 3.0

内容的提问来源于stack exchange,提问作者Daryl Odnert

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 08:54:03