All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jvmMain.io.mockk.impl.instantiation.JvmObjectMockFactory.kt Maven / Gradle / Ivy

package io.mockk.impl.instantiation

import io.mockk.InternalPlatformDsl.toStr
import io.mockk.MockKException
import io.mockk.MockKGateway
import io.mockk.MockKGateway.ObjectMockFactory
import io.mockk.impl.InternalPlatform
import io.mockk.impl.log.Logger
import io.mockk.impl.stub.MockType
import io.mockk.impl.stub.SpyKStub
import io.mockk.impl.stub.StubGatewayAccess
import io.mockk.impl.stub.StubRepository
import io.mockk.proxy.MockKAgentException
import io.mockk.proxy.MockKProxyMaker

class JvmObjectMockFactory(
    val proxyMaker: MockKProxyMaker,
    val stubRepository: StubRepository,
    val gatewayAccess: StubGatewayAccess
) : ObjectMockFactory {
    val refCntMap = RefCounterMap()

    override fun objectMockk(obj: Any, recordPrivateCalls: Boolean): () -> Unit {
        if (refCntMap.incrementRefCnt(obj)) {
            val cls = obj::class

            log.debug { "Creating object mockk for ${cls.toStr()}" }

            val stub = SpyKStub(
                cls,
                "object " + cls.simpleName,
                gatewayAccess,
                recordPrivateCalls,
                MockType.OBJECT
            )

            log.trace {
                "Building object proxy for ${cls.toStr()} hashcode=${InternalPlatform.hkd(
                    cls
                )}"
            }
            val cancellable = try {
                proxyMaker.proxy(
                    cls.java,
                    emptyArray(),
                    JvmMockFactoryHelper.mockHandler(stub),
                    false,
                    obj
                )
            } catch (ex: MockKAgentException) {
                throw MockKException("Failed to build object proxy", ex)
            }

            stub.hashCodeStr = InternalPlatform.hkd(cls.java)

            stub.disposeRoutine = cancellable::cancel

            stubRepository.add(obj, stub)
        }

        return {
            if (refCntMap.decrementRefCnt(obj)) {
                val stub = stubRepository.remove(obj)
                stub?.let {
                    log.debug {
                        "Disposing object mockk for ${obj::class.toStr()} hashcode=${InternalPlatform.hkd(
                            obj
                        )}"
                    }
                    it.dispose()
                }
            }
        }
    }

    override fun clear(
        obj: Any,
        options: MockKGateway.ClearOptions
    ) {
        stubRepository[obj]?.clear(options)
    }

    override fun clearAll(
        options: MockKGateway.ClearOptions,
        currentThreadOnly: Boolean
    ) {
        val currentThreadId = Thread.currentThread().id
        stubRepository.allStubs.forEach {
            if (currentThreadOnly && currentThreadId != it.threadId) {
                return@forEach
            }
            it.clear(options)
        }
    }

    companion object {
        val log = Logger()
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy