gpt4 book ai didi

scala - 有没有办法在 Scala 中模拟 Singleton 对象

转载 作者:行者123 更新时间:2023-12-04 01:53:46 25 4
gpt4 key购买 nike

我有以下代码:

trait Calculator {

def add(x:Int, y:Int):Int
def multiply(x:Int,y: Int):Int
}

trait MyCalculator extends Calculator {

override def add(x: Int, y: Int): Int = x+y //in real live it calls remote service which is not avaialble in test

override def multiply(x: Int, y: Int): Int = x*y //in real live it calls remote service which is not avaialble in test
}

object MyCalculator extends MyCalculator

现在我有计算器服务:

trait CalculatorServiceTrait {

def calculate(x:Int,sign:String,y:Int):Int
}

trait CalculatorService extends CalculatorServiceTrait{
override def calculate(x: Int, sign: String, y: Int): Int = {
sign match{
case "+" => MyCalculator.add(x,y)
case "*" => MyCalculator.multiply(x,y)
case _ => 0
}
}
}

object CalculatorService extends CalculatorService

现在我想使用 Mockito 模拟 MyCalculator 来给我带来不正确的结果。

 "Calculator Service" should{

"return 0 when 2 and 2 used " in{

val MyCalculatorMock = mock[MyCalculator]
when(MyCalculatorMock.multiply(2,2)).thenReturn(0)
class CalculatorServiceUnderTest extends CalculatorService with MyCalculator

new CalculatorServiceUnderTest with MyCalculator
val c = new CalculatorServiceUnderTest
val result = c.calculate(2,"+",2)
result shouldEqual(0)
}
}

但我仍然得到“4”而不是“0”

有没有办法处理这样的测试用例?

P.S:我可以更改一些类或 trait 实现,但进行全局重构可能会有问题

最佳答案

好吧,你的模拟对象没有在任何地方使用,所以,它永远不会被调用,这并不奇怪,是吗?

要回答你的问题,不,你不能模拟一个单例,这就是为什么像这样直接使用它几乎从来都不是一个好主意。需要从外部提供对组件的外部依赖项,以便组件能够独立测试。

做你想做的一种方法是使 CalculatorService 一个类,并将 MyCalculator 实例作为参数传递给构造函数:

class CalculatorService(calc: MyCalculator = MyCalculator) 
extends CalculatorServiceTrait {
override def calculate(x: Int, sign: String, y: Int): Int = sign match {
case "+" => calc.add(x,y)
case "*" => calc.multiply(x,y)
case _ => 0
}
}
}

然后,在您的测试中,您可以这样做:val testMe = new CalculatorService(mock[MyCalculator])

如果由于某种原因它必须保留一个特征,您可以使用“蛋糕模式”来提供外部依赖项:

trait CalculatorProvider {
def calc: MyCalculator
}

trait CalculatorService { self: CalculatorProvider =>
...
}

object CalculatorService extends CalculatorService with CalculatorProvider {
def calc = MyCalculator
}


val testMe = new CalculatorService with CalculatorProvider {
val calc = mock[MyCalculator]
}

关于scala - 有没有办法在 Scala 中模拟 Singleton 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37947271/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com