question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

NullPointerException while using 'and' matcher with capture

See original GitHub issue

Failure Information (for bugs)

I’ve updated:

  • mockk from 1.9.3 to 1.11.0
  • kotlin 1.4.30 to 1.5.10 and after that, the code below throws NPE.

Steps to Reproduce

Run code below

Context

  • MockK version: 1.11.0
  • OS: macos Catalina 10.15.7
  • Kotlin version: 1.5.10
  • JDK version: 11.0.10
  • JUnit version: 5.7.2
  • Type of test: unit test

Stack trace

java.lang.NullPointerException
	at org.proj.userservice.domain.model.DeviceToken.hashCode(domain.kt)
	at io.mockk.AndOrMatcher.hashCode(Matchers.kt)
	at java.base/java.util.ArrayList.hashCodeRange(ArrayList.java:627)
	at java.base/java.util.ArrayList.hashCode(ArrayList.java:614)
	at io.mockk.InvocationMatcher.hashCode(API.kt:3782)
	at java.base/java.util.HashMap.hash(HashMap.java:339)
	at java.base/java.util.HashMap.get(HashMap.java:552)
	at java.base/java.util.Collections$SynchronizedMap.get(Collections.java:2594)
	at io.mockk.impl.InternalPlatform.customComputeIfAbsent(InternalPlatform.kt:39)
	at io.mockk.impl.stub.MockKStub$childMockK$$inlined$synchronized$lambda$1.invoke(MockKStub.kt:192)
	at io.mockk.impl.recording.CommonCallRecorder.safeExec(CommonCallRecorder.kt:72)
	at io.mockk.impl.log.SafeToString.exec(SafeToString.kt:10)
	at io.mockk.impl.stub.MockKStub.childMockK(MockKStub.kt:191)
	at io.mockk.impl.recording.PermanentMocker.permamentize(PermanentMocker.kt:48)
	at io.mockk.impl.recording.PermanentMocker.mock(PermanentMocker.kt:24)
	at io.mockk.impl.recording.states.RecordingState.mockPermanently(RecordingState.kt:121)
	at io.mockk.impl.recording.states.RecordingState.round(RecordingState.kt:33)
	at io.mockk.impl.recording.CommonCallRecorder.round(CommonCallRecorder.kt:50)
	at io.mockk.impl.eval.RecordedBlockEvaluator.record(RecordedBlockEvaluator.kt:63)
	at io.mockk.impl.eval.EveryBlockEvaluator.every(EveryBlockEvaluator.kt:30)
	at io.mockk.MockKDsl.internalEvery(API.kt:92)
	at io.mockk.MockKKt.every(MockK.kt:98)


val kotestVersion = "4.6.0"
val kotestExtVersion = "1.0.0"

fun kotest(moduleName: String, version: String = kotestVersion) = "io.kotest:kotest-$moduleName-jvm:$version"
fun kotestExt(moduleName: String, version: String = kotestExtVersion) = "io.kotest.extensions:kotest-$moduleName:$version"

dependencies {
    testImplementation("org.junit.jupiter:junit-jupiter:5.7.2")
    testImplementation(kotest("runner-junit5"))
    testImplementation(kotest("property"))
    testImplementation(kotestExt("property-arrow")) {
        exclude("io.arrow-kt")
    }
    testImplementation(kotest("assertions-core"))
    testImplementation(kotestExt("assertions-arrow")) {
        exclude("io.arrow-kt")
    }
    testImplementation(kotestExt("extensions-testcontainers"))
    testImplementation(kotestExt("extensions-spring"))
    testImplementation(springBoot("test")) {
        exclude(module = "junit")
        exclude(module = "mockito-core")
    }
    testImplementation("io.mockk:mockk:1.11.0")
}

class Spec: FreeSpec({

    data class DevicePinToken(
      val userId: UUID,
      val deviceId: String,
      val creationTime: LocalDateTime
    )

    open class Mockks {
            val service: DeviceService = mockk()
            val deviceSlot = slot<DeviceToken>()
    
            init {
                every { // Failed here
                    service.upsertDeviceToken(
                        and(
                            capture(deviceSlot), 
                            match { it.deviceId == deviceId && it.userId == userId}
                        )
                    )
                } just Runs

     "any spec" {
            with(Mockks()) { // Mockks initialization failed

            }
     }
})

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:2
  • Comments:9 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
untracommented, Sep 28, 2021

I am reproducing this myself. glad I found someone has already made a github issue. defiantly looks like the and matcher calls equality operation, which calls hashcode, which tested objects may not define or be capable of responding to.

0reactions
gmazzocommented, Nov 30, 2022

It seems the one in the android codebase has this issue fixed already:

        if (classBeingRedefined == null) {
            return classfileBuffer
        }

https://github.com/mockk/mockk/blob/master/modules/mockk-agent-android/src/main/kotlin/io/mockk/proxy/android/transformation/InliningClassTransformer.kt#L30

So both InliningClassTransformer classes have diverged. I’m going to open a PR to fix the JVM one as well

Read more comments on GitHub >

github_iconTop Results From Across the Web

Spring-Boot: Mockito Captor: NullPointerException and ...
You should only call capture to stand in for an argument during a verify call, and then retrieve the captured value or values...
Read more >
How to Fix and Avoid NullPointerException in Java - Rollbar
NullPointerException in Java occurs when a variable is accessed which is not pointing to any object and refers to nothing or null.
Read more >
Handling Java NullPointerException and Best Practices
Java NullPointerException is an unchecked exception and extends RuntimeException. Learn why NullPointerException occur and how to handle it ...
Read more >
How to resolve the java.lang.NullPointerException - Educative.io
In Java, the java.lang.NullPointerException is thrown when a reference variable is accessed (or de-referenced) and is not pointing to any object.
Read more >
How to Handle NullPointerException in Java - freeCodeCamp
The reason you are getting this error is because we are trying to perform the length() operation on str1 which is null ....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found