Mockk:如何模拟保存对象时生成的对象ID答案+ vararg

问题描述

在测试中,我需要模拟一种情况,即使用实体管理器(em)将新对象保存到数据库中,并且在此过程中,该对象的id属性设置为自动递增数据库中该行的ID。我想将id属性设置为我自己的值,以便稍后在测试中进行匹配。

我正在使用模拟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,但是我在文档中找不到任何方法。欢迎使用改进技巧:)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...