【问题标题】:Scala: Mock init fails with Cats IO type parameterScala:模拟初始化因 Cats IO 类型参数而失败
【发布时间】:2018-03-08 23:25:39
【问题描述】:

在编写测试时,我遇到了以下异常:

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

使用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 看起来像这样:

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

DataAccessObject 是这样的:

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

我不知道如何修复/正确实施此问题。任何帮助,将不胜感激。谢谢!

【问题讨论】:

    标签: scala unit-testing mockito specs2 scala-cats


    【解决方案1】:

    试试

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

    基于此answer


    您应该尝试使用org.mockito.Mockito#when 而不是specs2s 内部方法匹配功能:

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

    而不是

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

    【讨论】:

    • 谢谢。确实如此,现在我得到了java.lang.ClassCastException: codegen.java.lang.Object$MockitoMock$546148877 cannot be cast to cats.effect.IO (null:-1)。我也会查看其他答案,也许我可以在那里找到一些提示。
    • 这行得通!所以我猜这是 specs2 mockito 包的问题。我将在他们的 github 上创建一个问题。非常感谢!如果您更新答案,我会接受。
    • 谢谢,已接受。仅供参考,我还必须使用 org.mockito.Mockito#when(m.createTable) thenReturn IO { Right[Throwable, Int](1) } 而不是 m.createTable returns IO { Right[Throwable, Int](1) }
    • 其实只需要改变我之前评论中描述的方法mock,而不是Mock的创建。我相应地更新了您的答案,请查看。
    • 这将在 specs2 4.0.0 中修复,请参阅 github.com/etorreborre/specs2/issues/603
    猜你喜欢
    • 1970-01-01
    • 2016-04-08
    • 1970-01-01
    • 2019-01-06
    • 1970-01-01
    • 2014-05-28
    • 1970-01-01
    • 1970-01-01
    • 2020-08-20
    相关资源
    最近更新 更多