8

For accessing objects, a Slick DAO which contains functions returning actions and objects of a stored type were created. Example:

def findByKeysAction(a: String, b: String, c: String = {
  Users.filter(x => x.a === a && x.b === b && x.c === c).result
}

def findByKeys(a: String, b: String, c: String): Future[Option[foo]] = {
  db.run(findByKeysAction(consumerId, contextId, userId)).map(_.headOption)
}

Notice how the non-action-based function wraps the other in db.run().

What is a solid approach to test both functions and minimizing redundancy of code?

I naive method could of course be to test them both with their individual test setups (above is a simple example; there could be a lot of test setup needed to satisfy DB restrictions).

Th 00 mÄ s
  • 3,776
  • 1
  • 27
  • 46

1 Answers1

5

Notice how the non-action-based function wraps the other in db.run().

Not really. Your findByKeys method does not call findByUserIdAction, so I'm adjusting for that minor detail in this answer.


def findByUserIdAction(userId: String) = {
  Users.filter(_.userId === userId).result
}

The above code returns a DBIOAction. As the documentation states:

Just like a query, an I/O action is only a description of an operation. Creating or composing actions does not execute anything on a database.

As far as a user of Slick is concerned, there is no meaningful test for a DBIOAction, because by itself it does nothing; it's only a recipe for what one wants to do. To execute the above DBIOAction, you have to materialize it, which is what the following does:

def findByUserId(userId: String): Future[Option[User]] = {
  db.run(findByUserIdAction(userId)).map(_.headOption)
}

The materialized result is what you want to test. One way to do so is to use ScalaTest's ScalaFutures trait. For example, in a spec that mixes in that trait, you could have something like:

"Users" should "return a single user by id" in {
  findByUserId("id3").futureValue shouldBe Option(User("id3", ...))
}

Take a look at this Slick 3.2.0 test project for more examples: specifically, TestSpec and QueryCoffeesTest.

In summary, don't bother trying to test a DBIOAction in isolation; just test its materialized result.

Jeffrey Chung
  • 19,319
  • 8
  • 34
  • 54
  • Corrected my code example and removed some of the noise. Sorry for the inconvenience please update your code accordingly if you have the time. Thanks! – Th 00 mÄ s Nov 24 '17 at 11:30