Scala中如何测试调用其他样例类的样例类并存根依赖返回值?
Scala样例类内部调用的存根实现方案
问题场景
你定义了两个Scala样例类:
case class First() { def run() = callSecondCaseClass() }
case class callSecondCaseClass() { // 执行一些操作并返回结果 }
想要测试First类时,存根callSecondCaseClass让它返回指定模拟值,但当前测试写法无法实现,需要调整代码结构来解耦依赖。
核心问题
原代码中First的run方法直接在内部实例化callSecondCaseClass,属于硬编码依赖,Mock框架无法拦截这种直接创建的对象,必须先重构解耦。
解决方案步骤
1. 重构代码解耦依赖
首先定义抽象特质封装callSecondCaseClass的行为,然后让First通过构造函数接收该特质的实例(同时保留默认值兼容原有逻辑):
// 定义抽象特质,描述callSecondCaseClass的核心行为 trait SecondHandler { def perform(): String // 替换成你实际的返回类型 } // 让原样例类实现该特质 case class CallSecondCaseClass() extends SecondHandler { override def perform(): String = { // 原有业务逻辑,返回结果 "真实结果" } } // 修改First类,通过构造函数注入依赖 case class First(handler: SecondHandler = CallSecondCaseClass()) { def run() = handler.perform() }
2. 编写测试代码(以Mockito为例)
创建SecondHandler的模拟实例,注入到First中,存根指定方法的返回值:
import org.mockito.Mockito._ import org.scalatest.flatspec.AnyFlatSpec import org.scalatestplus.mockito.MockitoSugar class FirstTest extends AnyFlatSpec with MockitoSugar { "First.run" should "返回存根的模拟值" in { // 创建模拟的SecondHandler val mockHandler = mock[SecondHandler] // 定义要返回的模拟值 val stubValue = "模拟结果" // 存根perform方法返回指定值 when(mockHandler.perform()).thenReturn(stubValue) // 传入模拟对象创建First实例 val first = First(mockHandler) val result = first.run() // 验证结果符合预期 assert(result == stubValue) } }
如果使用ScalaMock,代码类似:
import org.scalamock.scalatest.MockFactory import org.scalatest.flatspec.AnyFlatSpec class FirstTest extends AnyFlatSpec with MockFactory { "First.run" should "使用存根的SecondHandler结果" in { val mockHandler = mock[SecondHandler] val stubValue = "模拟结果" (mockHandler.perform _).expects().returning(stubValue) val first = First(mockHandler) val result = first.run() assert(result == stubValue) } }
原测试代码的问题
原代码中when(First.callSecondCaseClass).thenReturn(value)写法错误:
callSecondCaseClass是类名,不是First的成员方法,无法通过First.调用- 即使写法正确,
First内部直接new对象的逻辑无法被Mock框架拦截,必须通过依赖注入让外部可以替换实例
内容的提问来源于stack exchange,提问作者Programmer
相关产品推荐
相关产品推荐

