2

I'm having a heck of a time using a test database for my ScalaTest test cases, as shown in the documentation examples.

I have a default database, and a testdb database, and my Spec looks like

class JobSpec extends FlatSpec with AutoRollback {
  DBsWithEnv("test").setup('testdb)
  override def db = NamedDB('testdb).toDB

  override def fixture(implicit session:DBSession) = {
    User.insert("test_user")
  }

  it should "create a new user" in { implicit session: DBSession =>
    User.sqlFind("test_user") //succeeds
    User.dslFind("test_user") //fails
  }
}

It seems that my queries using the sql work, but the ones using the dsl do not. The DSL queries error, trying to access the 'default database, but the sql queries correctly use the 'testdb database. Here's the error

Connection pool is not yet initialized.(name:'default)
java.lang.IllegalStateException: Connection pool is not yet initialized.(name:'default)

Here's the User class

case class User(name: String)
object User extends SQLSyntaxSupport[User] {
  def apply(u: SyntaxProvider[User])(rs: WrappedResultSet) = apply(u.resultName)(rs)
  def apply(j: ResultName[User])(rs: WrappedResultSet) = new User(rs.get(u.name))

  override val tableName = "users"
  val u = User.syntax("u")

  def dslFind(name: String)(implicit session: DBSession) = 
    withSQL {
      select.from(User as u).where.eq(u.name, name)
    }.map(User(u)).single().apply()
  def sqlFind(name: String)(implicit session: DBSession) = 
    sql""" select (name) from users where name = $name;"""
      .map(rs => new User(rs.string(1)).single().apply()
}

Anyone know why it is trying to use the default database instead of the testdb, when calling DSL-created queries? Thanks!

Josh Lemer
  • 446
  • 3
  • 18

1 Answers1

4

You need to override your SQLSyntaxSupport like this:

override val connectionPoolName = 'testdb

The reason for that is that SQLSyntaxSupport fetches columns from JDBC metadata when accessing for the first time.

http://scalikejdbc.org/documentation/sql-interpolation.html

If you prefer to avoid automatically accessing metadata, override columns or use autoColumns macros.

https://github.com/scalikejdbc/scalikejdbc/blob/2.2.8/scalikejdbc-syntax-support-macro/src/test/scala/foo/AutoSpec.scala#L20

Synesso
  • 37,610
  • 35
  • 136
  • 207
Kazuhiro Sera
  • 1,822
  • 12
  • 15
  • Thanks, but then how should I actually do this? I can't hardcode testdb in the `User` object, since I only want it to use the testdb when testing. – Josh Lemer Sep 10 '15 at 22:57
  • 1
    Like take these test examples http://scalikejdbc.org/documentation/testing.html, is it implied that the Member class hardcodes `'testdb`? But then how can Member be used on the normal db? And I can't make a User class that has TestUser and DefaultUser objects implementing it with a connectionPoolName, since the User must itself be an object. – Josh Lemer Sep 10 '15 at 23:18
  • testdb is just a name for connection pool. Using the same name when both of production and testing is straightforward. You can switch how the connection pool works with config file. – Kazuhiro Sera Sep 12 '15 at 03:19
  • Thanks for autoColumns clue! – Paul Lysak Dec 01 '16 at 17:14
  • @KazuhiroSera is there any concrete example "straightforward" usage of same name for production and testing? – NikolaS Aug 18 '22 at 08:31