【问题标题】:Why when I unit test do I get coverage points with `final lazy val` but not `final val`?为什么当我进行单元测试时,我会用`final lazy val`而不是`final val`获得覆盖点?
【发布时间】:2015-09-25 22:30:13
【问题描述】:

我有一些代码(项目源代码在这里 - https://github.com/natemurthy/testing-final-vals):

object Main extends App {
  final val NAME = "foo"
}

我正在使用 ScalaTest 和 SBT Coverage 插件来测试此代码,如下所示:

import org.scalatest.{FlatSpec,Matchers}

class MainTest extends FlatSpec with Matchers {
  it should "have a name" in {
    Main.NAME shouldBe "foo"
  }
}

但由于某种原因,我只有在此表达式中包含 lazy 修饰符时才能获得覆盖点:

为什么会这样?

【问题讨论】:

  • vals 已经是最终版本,因此您不需要 final 修饰符。
  • @SteveChaloner:不,可以覆盖类的val,所以val通常不是final。
  • @senia 我在考虑objects(不能覆盖),但很好。
  • final val(没有显式返回类型)是 Scala 中的编译时常量,它在运行时不存在,因此无需覆盖。

标签: java scala sbt scalatest


【解决方案1】:

我的猜测是覆盖工具会计算已执行的行数。

final val NAME = "foo" 被编译为字节码中的常量内联值,如 Java 中的 private static final。访问变量时,您只需从字节码常量中读取值。 More Info on inlining constant values during compiling

另一方面,final lazy val NAME = "foo" 编译为惰性构造方法,因为 JVM 中没有惰性值。如果您访问此变量,则会执行惰性构造方法。 More info on scala lazy value bytecode generation

【讨论】:

  • @nmurthy 是的。我修正了我的错字var 在这种情况下没有意义
猜你喜欢
  • 2012-11-04
  • 2012-08-31
  • 2014-10-12
  • 1970-01-01
  • 2021-07-29
  • 1970-01-01
  • 2019-09-14
  • 1970-01-01
  • 2011-11-29
相关资源
最近更新 更多