3
votes

I am new to scala (long time java developer). I tried to understand implicit and I think I understand the basics however I do not understand why it does not find the implicit value session. I tried to describe my problem with as much information as possible.

I followed the following blog post: http://blog.websudos.com/2015/04/04/a-series-on-phantom-part-1-getting-started-with-phantom/

Everything went/compiled fine until I wanted to test it. Getting the following error:

Error:(15, 46) could not find implicit value for parameter session: com.datastax.driver.core.Session
    Await.result(Database.autocreate().future(), 5.seconds)
                                             ^
Error:(20, 48) could not find implicit value for parameter session: com.datastax.driver.core.Session
    Await.result(Database.autotruncate().future(), 5.seconds)
                                               ^

when I execute the following test class:

import org.joda.time.DateTime
import org.scalatest.{BeforeAndAfterAll, FlatSpec}

import scala.concurrent.Await
import scala.concurrent.duration._

class DatabaseTest extends FlatSpec with BeforeAndAfterAll{
  override def beforeAll(): Unit = {
    super.beforeAll()
    Await.result(Database.autocreate().future(), 5.seconds)
  }

  override def afterAll(): Unit = {
    super.afterAll()
    Await.result(Database.autotruncate().future(), 5.seconds)
  }

  "A TwitterMessage" should "be stored in cassandra" in {
    val twitterMessageBefore = TwitterMessage(1L, DateTime.now, "This is a message", "me", "none")

    Database.twitterMessages.store(
      twitterMessageBefore
    )

    val twitterMessageAfter:Option[TwitterMessage] = Await.result(Database.twitterMessages.getById(1L), 5.seconds)

    assert(twitterMessageAfter.isDefined, "No entry was found regarding the id.")

    assert(twitterMessageAfter.get equals twitterMessageBefore)
  }
}

I also copied the other classes I wrote below:

TwitterMessages.scala

import com.websudos.phantom.dsl._

import scala.concurrent.Future

case class TwitterMessage (
  id: Long,
  timestamp: DateTime,
  msg: String,
  user: String,
  category: String
)

sealed class TwitterMessages extends CassandraTable[ConcreteTwitterMessages, TwitterMessage]{
  object id extends LongColumn(this) with PartitionKey[Long]
  object timestamp extends DateTimeColumn(this)
  object msg extends StringColumn(this)
  object user extends StringColumn(this)
  object category extends StringColumn(this)

  def fromRow(row: Row): TwitterMessage = {
    TwitterMessage(
      id(row),
      timestamp(row),
      msg(row),
      user(row),
      category(row)
    )
  }
}

abstract class ConcreteTwitterMessages extends TwitterMessages with RootConnector{
  def store(twitterMessage: TwitterMessage): Future[ResultSet] = {
    insert.value(_.id, twitterMessage.id)
      .value(_.timestamp, twitterMessage.timestamp)
    .value(_.msg, twitterMessage.msg)
    .value(_.user, twitterMessage.user)
    .value(_.category, twitterMessage.category)
    .consistencyLevel_=(ConsistencyLevel.ALL)
    .future()
  }

  def getById(id: Long): Future[Option[TwitterMessage]] = {
    select.where(_.id eqs id).one()
  }
}

Database.scala

import com.websudos.phantom.connectors.{ContactPoint, KeySpaceDef}

object Defaults {
  val connector = ContactPoint.local.keySpace("twitter")
}

class Database(val keyspace:KeySpaceDef) extends com.websudos.phantom.db.DatabaseImpl(keyspace){
  object twitterMessages extends ConcreteTwitterMessages with keyspace.Connector
}

object Database extends Database(Defaults.connector)
1

1 Answers

5
votes

To specifically address your problem, all you have to do is to mix in the connector into the the test suite. This one is on me as I forgot to update the blog post with this information.

class DatabaseTest extends FlatSpec with BeforeAndAfterAll
  with Defaults.connector.Connector