在我的测试中,我需要模拟一种情况,当使用实体管理器(em
)将新对象保存到数据库中时,在此过程中,该对象的id
属性设置为数据库中该行的自动递增ID。我想将该id
属性设置为我自己的值,以便稍后在测试中进行匹配。
我正在使用Mockk 1.9.3和Kotlin 1.4.0。
到目前为止,我有这个:
val myVal = 123
every {
em.persist(any<MyObj>())
} answers {
firstArg<MyObj>().id = myVal
// return of the persist method
em
}
编辑: em.persist
方法如下所示,问题可能与第一个参数为vararg有关。open fun persist(vararg o: Any?): T {
o.forEach { doThePersist(it) }
return this as T
}
但是,当我尝试运行该代码时,我得到:java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class MyObj
看起来问题出在firstArg
调用中。如果我在该行上放置一个断点,它将到达并停在那里,当我尝试评估firstArg<MyObj>()
时会发生异常。在文档中,我仅能找到使用简单Int的示例或有关如何匹配varargs的示例。有什么想法为什么会引发
ClassCastException
或如何在answers
部分中正确处理varargs?
最佳答案
就像МихаилНафталь在他的评论中指出的那样,如果模拟方法使用varargs,则将参数作为第一个参数中的数组传递到answers
lambda中。此解决方案适用于我的情况:
val myVal = 123
every {
em.persist(any<MyObj>())
} answers {
val myObj = firstArg<Array<*>>()[0].id as MyObj
myObj.id = myVal
// return of the persist method
em
}
我不必在every
节中为varargs使用特殊的匹配器,因为在我的情况下,只需要匹配第一个参数。也许在
answers
部分中有更优雅的处理varargs的方法,但是我在文档中找不到任何方法。欢迎使用改进技巧:)
关于kotlin - Mockk:如何模拟保存对象时生成的对象ID(答案+变量),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64226665/