mockito-kotlin
mockito-kotlin copied to clipboard
IncompatibleClassChangeError when using argThat
I get an IncompatibleClassChangeError
with any use of the argThat
matcher. Full stacktrace: https://pastebin.com/4hr67L0r. I am using version 2.0.0
.
Here is a simple example I replicated the problem with:
interface Foo {
fun doIt(arg: Int): Int
}
class TestClass {
@Test
fun testIt() {
mock<Foo> {
on { doIt(argThat { true }) } doReturn 0
}
}
}
@Octogonapus I get a NullPointerException with the provided example. This is caused by Mockito.argThat
which Mockito-kotlin uses under the hood. If you check the javadoc on Mockito.argThat
they recommend you to use booleanThat
instead:
class TestClass {
@Test
fun testIt() {
val mock = mock<Foo> {
on { doIt(booleanThat { true } doReturn 0
}
}
}
This should pass.
@bohsen Foo::doIt()
does not take a boolean, so I can't use booleanThat
. In my real code, it takes a complex argument so I think I need to use argThat
.
@Octogonapus In that case just call equals
inside argThat
(if equals is an option for the given argument). Example using a data class
as argument:
interface Foo {
fun doIt(arg: DataClass): Int
}
data class DataClass(i: Int, b: Boolean, s: String)
class TestClass {
@Test
fun testIt() {
val data = DataClass(42, true, "foobar")
val mock = mock<Foo> {
on { doIt(argThat { equals(data) } doReturn 0
}
myObjectThatCallsMyMock.baz(data)
... verify ...
}
}
Otherwise use an ArgumentMatcher.
Hm, that is what I was trying to do. I am starting to think my example was a bit too simple. Here is the actual code:
val mockWristIdentifier = mock<WristIdentifier> {
on { isSphericalWrist(or(wrist, wrist2)) } doReturn Option.empty()
on {
isSphericalWrist(argThat {
!(equals(wrist) || equals(wrist2))
})
} doReturn Option.just(ClassifierError(""))
}
My intent is to return Option.empty()
for either wrist
or wrist2
and return Option.just(ClassifierError(""))
otherwise. Does this look like the right usage to you?
Hi folks,
I get the same exception when using "check". My example:
doReturn(stuff).whenever(mock).fetchData(check {
assertThat(it.dayOfYear).isEqualTo(otherDate.dayOfYear)
assertThat(it.year).isEqualTo(otherDate.year)
})
Exception is:
java.lang.IncompatibleClassChangeError: Implementing class at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:763) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) at java.net.URLClassLoader.defineClass(URLClassLoader.java:467) at java.net.URLClassLoader.access$100(URLClassLoader.java:73) at java.net.URLClassLoader$1.run(URLClassLoader.java:368) at java.net.URLClassLoader$1.run(URLClassLoader.java:362) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:361) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349) at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
When debugging, I can see that the code is trying to load a class by name path.to.clazz.MyTest$givenApiReturns$$inlined$check$1
which (obviously I would say) fails, because this clazz cannot exists.
On:
- Kotlin 1.3.11
- mockito-kotlin 1.6.0
@Octogonapus @timbaer I had same issue with mockito-kotlin 2.1.0 and I fixed it by adding explicit dependency to mockito-core 2.23.0
Also running into NullPointerExceptions with mockito-kotlin 2.1.0
Adding explicit dependency to testImplementation("org.mockito:mockito-core:2.23.0")
solve the issue for me, thanks @kevcodez