5

I have some code (project source available here - https://github.com/natemurthy/testing-final-vals):

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

And I'm using ScalaTest and the SBT Coverage plugin to test this code like so:

import org.scalatest.{FlatSpec,Matchers}

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

But for some reason I only get coverage points when I include a lazy modifier in this expression:

enter image description here

enter image description here

Why is this the case?

Community
  • 1
  • 1
nmurthy
  • 1,337
  • 1
  • 12
  • 24

1 Answers1

7

My Guess is that the coverage tool counts executed lines.

final val NAME = "foo"is compiled as a constant inline value in bytecode like private static final in Java. When accessing the variable you just read the value from the bytecode constant. More Info on inlining constant values during compiling

final lazy val NAME = "foo"on the other hand compiles into a lazy construction method since there are no lazy values in the JVM. If you access this variable the lazy construction method is executed. More info on scala lazy value bytecode generation

Lukas Eichler
  • 5,689
  • 1
  • 24
  • 43