3

I'm using Scalatest and Slick 3.1.1 and I want to mock Database to be able to return what I need. I've tried Scalamock. It doesn't even compile. And I've tried Mockito. It compiles, but mock always return null instead of specified Future. As I understand it has something to do with matchers and generics, but I don't know how can I fix it. Here is what I've tried:

// action what I need to execute
def findById(id: UUID): DBIOAction[Option[TaskResult], NoStream, Read] =
    taskResultTable.filter(_.taskId === id).result.headOption

// mock with generics specified explicitly
val mockedDb = Mockito.mock(classOf[Database])
Mockito.when(mockedDb.run(Matchers.any[DBIOAction[Option[TaskResult], NoStream, Read]]()))
  .thenReturn(Future.failed(new Exception))
val f = mockedDb.run(findById(UUID.randomUUID()))
println(f)
// f is null



// mock without explicit generics
val mockedDb = Mockito.mock(classOf[Database])
Mockito.when(mockedDb.run(Matchers.any()))
  .thenReturn(Future.failed(new Exception))
val f = mockedDb.run(findById(UUID.randomUUID()))
println(f)
// f is null



// mock with exact action
val mockedDb = Mockito.mock(classOf[Database])

val action = findByIds(Seq(UUID.randomUUID()))
Mockito.when(mockedDb.run(action))
  .thenReturn(Future.failed(new Exception))

val futureFromSpecifiedAction = mockedDb.run(action)
println(futureFromSpecifiedAction)
// futureFromSpecifiedAction is not null and what I need

val differentAction = findByIds(Seq(UUID.randomUUID()))
val futureFromDifferentAction = mockedDb.run(differentAction)
println(futureFromDifferentAction)
// futureFromDifferentAction is null

I only have success if I specify exact same action that will be passed to run and obviously it can't be achieved in tests. What am I doing wrong here?

Artem Malinko
  • 1,761
  • 1
  • 22
  • 39
  • This is quite difficult to achieve due to how Slick uses implicit values for some of the query creation values. I haven't found a way to do this despite trying for a long time. It's a major drawback of Slick IMHO. – jkinkead Aug 04 '16 at 21:26
  • `run` is final, you cannot mock it out this way. I have had a pain mocking the database object myself. – nlucaroni Jan 13 '17 at 15:51

0 Answers0