In my test I need to mock a situation, when new object is saved into database using entity manager (em
) and during that process, id
property of that object is set to auto-incremented id of that row in database. I would like to set that id
property to my own value that I could match later in the test.
I'm using mockk 1.9.3 and kotlin 1.4.0.
So far I have this:
val myVal = 123
every {
em.persist(any<MyObj>())
} answers {
firstArg<MyObj>().id = myVal
// return of the persist method
em
}
Edit: The em.persist
method looks like this, problem is probably related to first argument being vararg.
open fun persist(vararg o: Any?): T {
o.forEach { doThePersist(it) }
return this as T
}
But when I try to run that code, I get:
java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class MyObj
Looks like the problem is in the firstArg
call. If I place a breakpoint on that line, it will reach it and stop there, the exception occurs when I try to evaluate firstArg<MyObj>()
.
In documentation I was able to find only example using simple Int or example on how to match varargs. Any ideas why the ClassCastException
is thrown or how to handle the varargs properly in answers
section?
As Михаил Нафталь pointed out in his comment, if the mocked method uses varargs, the arguments are passed into
answers
lambda as an array in the first argument. This solution works for my case:I don't have to use special matcher for varargs in
every
section, as I need to match only the first argument in my case.Maybe there is more elegant way of handling varargs in the
answers
section, but I was not able to find any in the docs. Improvement tips welcome :)