0

Consider the following test:

class BookTest extends FlatSpec with Matchers with ScalaFutures with BeforeAndAfter
{
  implicit val defaultPatience =
    PatienceConfig(timeout = Span(5, Seconds), interval = Span(500, Millis))

  val db = Database.forURL("jdbc:sqlite:/home/myhome/test.sqlite", driver = "org.sqlite.JDBC")

  private val books = Books.all

  val setup = DBIO.seq(
    // Create the tables, including primary and foreign keys
    (books.schema).create,

    // Insert some dummy data
    books += new Book(-1, 0, "Awesome Title #1"),
    books += new Book(-1, 1, "Gorgeous successor"),
    books += new Book(-1, 2, "Nasty prequel")
  )

  db.run(setup)

  "Books" should "be a Sequences of Books" in
  {
    val bookList = db.run(books.result)
    whenReady(bookList)
    {
      result => result shouldBe a [Seq[Int]]
    }
  }

  "Books" should "contain the books we inserted" in
  {
    val bookList: Future[Seq[Book]] = db.run(books.result)
    whenReady(bookList)
    {
      result =>
      {
        println("TYPE OF RESULT:" result)
        result.length === 1334
      //  result(0).title === "Awesome Title #1"
      }
    }
  }

I explicitly stated the type of bookList, which is a Sequence of Books, wrapped in a future.

Now I would expect result shouldBe a [Seq[Int]] to fail, because Seq[Int] != Seq[Book]

Also the second test returns true, but why? The length of the result should be 3... it always passes.

Where am I thinking wrong? Doesn't whenReady(bookList) combined with the defaultPatience and the Future do what I expect it to do?

edit: Just to make this clear, the database is created and it's filled, so that works (verified with sqlite3 ;))

edit: How I solved both problems:

1)

"Books" should "be a Sequences of Books" in
  {
    val bookList: Future[Seq[Book]] = db.run(books.result)
    whenReady(bookList)
    {
      result => {
        result shouldBe a [Seq[_]] // Remember type erasure
        result(0) shouldBe a [Book]
      }

    }
  }

2) (which was really dumb, but ya..)

"Books" should "contain the books we inserted" in
  {
    val bookList = db.run(books.result)
    whenReady(bookList)
    {
      result =>
      {
        result.length shouldBe 3
        result(0).title shouldBe "Awesome Title #1"
      }
    }
  }

1 Answers1

0

You are hit by JVM type erasure. From ScalaTest Using matchers:

Because type parameters are erased on the JVM, we recommend you insert an underscore for any type parameters when using this syntax. Both of the following test only that the result is an instance of List[_], because at runtime the type parameter has been erased:

result shouldBe a [List[_]] // recommended
result shouldBe a [List[Fruit]] // discouraged

In the second test there is no should or assert, just a fruitless result.length === 1334. As described in Checking equality with matchers:

result.length should === (1334)

or

result.length shouldBe 1334
Suma
  • 33,181
  • 16
  • 123
  • 191
  • That explains the first issue, but now why it's okay with `size == 1337` when it's actually just 3 elements in there. –  Dec 18 '15 at 22:13
  • 1
    @Teolha because you are doing a fruitless comparison. not using the result in any "should" or "assert". – Suma Dec 18 '15 at 23:27
  • Thank you... I should not program after work, it's just no good *g* Thanks a lot, everything works now... well, with sqlite that is, with h2 no luck at all –  Dec 19 '15 at 07:55