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()
}
}