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

2023-12-25

我有以下代码:

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:我可以更改某些类或特征实现,但进行全局重构可能会出现问题


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

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

做你想做的事情的一种方法是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]
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

有没有办法在 Scala 中模拟 Singleton 对象 的相关文章

  • Java 拥有闭包后 Scala 的优势 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 随着 Java 中添加了闭包 作为语言选择 Scala 相对于 Java 的优势是什么 有人可以详细说明一下有什么优点吗 除了闭包 J
  • 正确使用术语 Monoid

    从下面的例子来看 我认为这样的说法是正确的String在串联运算下定义了一个幺半群 因为它是关联二元运算 并且String碰巧有一个身份元素 它是一个空字符串 scala gt Jane Doe Jane Doe res0 Boolean
  • 使用 Mockito 模拟某些方法,但不模拟其他方法

    有没有办法使用 Mockito 模拟类中的某些方法 而不模拟其他方法 例如 在这个 诚然是人为的 Stock我想嘲笑的班级getPrice and getQuantity 返回值 如下面的测试片段所示 但我想要getValue 执行乘法 如
  • 单元测试失败,异常代码为 c0000005

    我正在尝试使用本机单元测试项目在 Visual Studios 2012 中创建单元测试 这是我的测试 TEST METHOD CalculationsRoundTests int result Calculations Round 1 0
  • Scala 和 Python 的通行证

    我想知道 是否有相当于 python 的 pass 表达式 这个想法是编写没有实现的方法签名 并编译它们只是为了对某些库原型的这些签名进行类型检查 我能够使用以下方法模拟这种行为 def pass A A throw new Excepti
  • 如何关闭 Scala 中因方法重载而导致代码无法编译的特定隐式?

    我正忙着尝试自己回答这个问题 Scala Play 2 4 x 通过 anorm MySQL 处理扩展字符到 Java Mail https stackoverflow com questions 31417718 scala play 2
  • 如何在不从 DataFrame 转换并访问它的情况下向数据集添加列?

    我知道使用以下方法将新列添加到 Spark 数据集的方法 withColumn and a UDF 它返回一个 DataFrame 我还知道 我们可以将生成的 DataFrame 转换为 DataSet 我的问题是 如果我们仍然遵循传统的
  • 在spark-kafka中使用schema将ConsumerRecord值转换为Dataframe

    我正在使用 Spark 2 0 2 和 Kafka 0 11 0 并且 我正在尝试在火花流中使用来自卡夫卡的消息 以下是代码 val topics notes val kafkaParams Map String Object bootst
  • 通过 Web 界面执行 python 单元测试

    是否可以通过 Web 界面执行单元测试 如果可以 如何执行 EDIT 现在我想要结果 对于测试 我希望它们是自动化的 可能每次我对代码进行更改时 抱歉我忘了说得更清楚 EDIT 这个答案此时已经过时了 Use Jenkins https j
  • 什么是适合 Rails 3 的测试框架?

    去年我一直在使用 Ruby On Rails 但是 无法进行单元测试 现在我必须编写单元测试代码 哪个测试框架好 为什么 有这方面的好的教程吗 我的系统配置 Ruby 1 9 2 Rails 3 Ubuntu 10 第一个技巧是 尝试升级到
  • 了解 Spark 中的 DAG

    问题是我有以下 DAG 我认为当需要洗牌时 火花将工作划分为不同的阶段 考虑阶段 0 和阶段 1 有些操作不需要洗牌 那么为什么 Spark 将它们分成不同的阶段呢 我认为跨分区的实际数据移动应该发生在第 2 阶段 因为这里我们需要cogr
  • 如何通过删除 Scala 中的一个元素来从列表中获取所有可能的子列表?

    我有一个清单List 1 2 3 4 并希望通过删除一个元素来获得所有子列表 List 2 3 4 List 1 3 4 List 1 2 4 List 1 2 3 做到这一点最简单的方法是什么 如果你的意思是 离开每个position在列
  • sbt 找不到启动器 jar:./bin/sbt-launch.jar

    我已经成功地使用 sbt 进行基本的 Scala 编译好几年了 但有一天它由于某种原因停止工作 我在自己的帐户中使用它 但我决定让我的系统管理员在我们的本地网络上安装最新版本 当我尝试运行它时 我得到 找不到启动器 jar bin sbt
  • 将下划线分配给变量。下划线是做什么的?

    最近我遇到了这样的代码 var myVariable variableKind 这似乎是一种分配方式null to myVariable 谁能解释一下背后的理由 在这种情况下 分配之间有什么区别 and null到一个变量 它使用默认值初始
  • 解决 sbt 中 jar 加载冲突的问题

    当两个特定的 sbt 插件启动时 我在 sbt 启动时收到以下错误加在一起到其构建定义中的项目 这些 sbt 插件之一是规模化jdbc https github com scalikejdbc scalikejdbc另一个是my own h
  • IQueryable 单元或集成测试

    我有一个 Web api 并且公开了一个端点 如下所示 api 假期 name name 这是 Web api 的控制器 get 方法 public IQueryable
  • Scala 为了在 JVM 上运行做出了哪些妥协?

    Scala 是一种很棒的语言 但我想知道如果它有自己的运行时 如何改进 IE 由于 JVM 的选择 做出了哪些设计选择 我所知道的两个最重要的妥协是 类型擦除 http java sun com docs books tutorial ja
  • Spark:导入UTF-8编码的文本文件

    我正在尝试处理一个包含很多特殊字符的文件 例如德语变音符号 o 等 如下所示 sc hadoopConfiguration set textinputformat record delimiter r n r n sc textFile f
  • 在为 RXJS 可观察量编写测试时,如何避免让调度程序通过我的业务逻辑?

    我发现使某些测试通过的唯一方法是显式地将调度程序传递给函数 为了便于说明 请考虑以下函数 function doStuff stream return stream delay 100 filter x gt x 2 0 map x gt
  • Slick:将操作与 DBIOAction 的 Seq 组合起来

    我有 工作 以下代码 val actions for lt slickUsers insertOrUpdate dbUser loginInfo lt loginInfoAction lt slickUserLoginInfos DBUse

随机推荐