Question

I need to import different libraries and do slightly different things depending on the use of my source, ie for running and testing.

If I have various source files that look something like this for production:

import scala.slick.driver.PostgresDriver.simple._
import Database.threadLocalSession

case class SomeBusinessObject(...)

What is good way to change it into the following for testing (meaning I would like to use a different databse during testing):

import scala.slick.driver.h2.simple._
import Database.threadLocalSession

case class SomeBusinessObject(...)

Oh, and then there's also a database class to hold the key to whatever database I'm using:

import scala.slick.driver.PostgresDriver.simple._

// Use the implicit threadLocalSession
import Database.threadLocalSession

object DB{

  val get = {
      Database.forURL("jdbc:postgresql:test:slick",
                           driver="org.postgresql.Driver",
                           user="postgres",
                           password="xxxx") 
  }
}

I did some research, and it looks like the Cake pattern may hold the key for this type of thing, but it would be great if someone could get me started (if cake's the right approach)

UPDATE:

Since asking this question, I found exactly what I was looking for in the Slick examples. It really sets it apart neatly! I worked through the examples some weeks back, but could not recall where I saw this done.

Was it helpful?

Solution

You could build on the fact that scala allows you to use "import" nested in a class, object or trait (and not just at the root level):

An example with scala.collection.mutable.Map and scala.collection.immutable.Map (say we want to use the immutable version of Map in test and the mutable one in Production)

scala> trait Import1 {
     | import scala.collection.mutable.{Map => iMap}
     | def Test = iMap(1 -> "a")
     | }
defined trait Import1

scala> trait Import2 {
     | import scala.collection.immutable.{Map => iMap}
     | def Test = iMap(1 -> "a")
     | }
defined trait Import2

now you can do:

scala> object ProductionThing extends Import1
defined module ProductionThing

scala> ProductionThing.Test
res6: scala.collection.mutable.Map[Int,java.lang.String] = Map(1 -> a)

scala> object TestingThing extends Import2
defined module TestingThing

scala> TestingThing.Test
res7: scala.collection.immutable.Map[Int,java.lang.String] = Map(1 -> a)

or you could use the same mechanism to scope your import within a class and inject that class into SomeBusinessObject.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top