Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala - unit test setup (use access modifier qualifiers?)

I'm new to Scala (from Java) and I like to develop TDD/BDD. So before knowing much about Scala I've already dived into Scalatest.

I'm wondering what you think is a good access strategy for unit testing, from the viewpoint that you want to test as much as possible.

Suppose I have a class World that I want to test and a class Agent that should not know everything about the World.

package program {
  package world {
    class World {
      private var notForAgent
      def forAgentDuringActing
      // forAgentDuringActing has an important side effect in notForAgent
    } 
  }

  package agent {
    class Agent
    // would call World.forAgentDuringActing
  }

  package world.test {
    class WorldSpec extends FunSpec {
      describe("The world") {
        it("should have side-effect behaviour when the agent acts on it") {
          // ... the test ...
        }
      }
    }
  }
}

Note that these package declarations are not sacred to me. What I really would like, is that WorldSpec would be something like a companion object to World, so that it can test for the side effect.

I thought maybe access modifier qualifiers would help. I could say private[world] notForAgent, but that really is more access than I would like. What I actually would like is something like private[this, test.WorldSpec] notForAgent, but I don't think multiple qualifiers are allowed.

What would you do to make this testable? Alternatively, can you indicate where my thoughts go in the wrong direction?

p.s. I know the statement "never test privates". But I also know the opinion "Testing is more important than the code itself. Alter access modifiers if it's needed for testing". However, I would like to avoid that discussion in this thread.

like image 628
qkrijger Avatar asked Jun 11 '12 16:06

qkrijger


1 Answers

If you're asking "How to test private methods?", then ScalaTest actually supports this. See here.

class C {
  private def m(x: Int) = x
}

class CTests extends /*any test suite you like*/ with PrivateMethodTester {
  val decoratedM = PrivateMethod[Int]('m)
  val c = new C
  val actual = c invokePrivate decoratedM(4711)
  val expected = 4711
  actual should be(expected) // this line depends on the test suite you've chosen
}
like image 140
agilesteel Avatar answered Sep 30 '22 13:09

agilesteel