Search code examples
scalaunit-testingmockitospecs2scala-cats

Scala: Mock init fails with Cats IO type parameter


While writing tests I'm confronted with the following exception:

java.lang.ClassCastException: codegen.java.lang.Object$MockitoMock$641592186 cannot be cast to cats.effect.IO (MyRepositorySpec.scala:19)

Which occurs when running this test code with specs2:

class MyRepositorySpec extends Specification with Mockito with TestData {
    ...
    val m = mock[MyDAO[IO]].smart
    m.createTable returns IO { Right[Throwable, Int](1) } // <- this is line 19

    val r = new MyRepository[IO](m)
    r.setup.unsafeRunSync() must beNone
    ...
}

MyDAO looks like this:

class MyDAO[M[_] : Monad](val transactor: Transactor[M])(implicit val AE: ApplicativeError[M, Throwable]) extends DataAccessObject[M, MyObject]

and the DataAccessObject like this:

trait DataAccessObject[M[_], T <: Entity]

I'm at a loss how to fix/correctly implement this. Any help would be appreciated. Thank you!


Solution

  • Try

    class IOMyDAO(override val transactor: Transactor[IO]) extends MyDAO[IO](transactor)
    
    val m = mock[IOMyDAO].smart
    

    Based on this answer.


    You should try to use org.mockito.Mockito#when instead of specs2s internal metod matching functionality:

    when(m.createTable) thenReturn IO { Right[Throwable, Int](1) }
    

    instead of

    m.createTable returns IO { Right[Throwable, Int](1) }