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

main.tech.apter.junit.jupiter.robolectric.internal.JUnit5RobolectricSandboxBuilder.kt Maven / Gradle / Ivy

Go to download

This repository aims to bridge the gap between JUnit 5 and Robolectric, enabling developers to leverage the benefits of both frameworks for unit testing Android applications. While Robolectric currently lacks a dedicated JUnit 5 extension, this project proposes a community-driven solution to achieve seamless integration.

The newest version!
package tech.apter.junit.jupiter.robolectric.internal

import org.robolectric.ApkLoader
import org.robolectric.annotation.SQLiteMode
import org.robolectric.internal.AndroidSandbox
import org.robolectric.internal.AndroidSandbox.SdkSandboxClassLoader
import org.robolectric.internal.ResourcesMode
import org.robolectric.internal.SandboxManager
import org.robolectric.internal.bytecode.ClassInstrumentor
import org.robolectric.internal.bytecode.InstrumentationConfiguration
import org.robolectric.internal.bytecode.ShadowProviders
import org.robolectric.pluginapi.Sdk
import tech.apter.junit.jupiter.robolectric.internal.extensions.createLogger
import tech.apter.junit.jupiter.robolectric.internal.extensions.outerMostDeclaringClass
import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject

internal class JUnit5RobolectricSandboxBuilder @Inject constructor(
    private val testClassContainer: TestClassContainer,
    private val apkLoader: ApkLoader,
    @Suppress("VisibleForTests")
    private val testEnvironmentSpec: AndroidSandbox.TestEnvironmentSpec,
    private val shadowProviders: ShadowProviders,
    private val classInstrumentor: ClassInstrumentor,
) : SandboxManager.SandboxBuilder {
    private inline val logger get() = createLogger()

    override fun build(
        instrumentationConfig: InstrumentationConfiguration,
        runtimeSdk: Sdk,
        compileSdk: Sdk,
        resourcesMode: ResourcesMode,
        sqLiteMode: SQLiteMode.Mode,
    ): AndroidSandbox {
        val testClass = testClassContainer.testClass
        logger.trace { "build AndroidSandbox[$runtimeSdk] ${testClass.name.substringAfterLast('.')}" }
        val sdkSandboxClassLoader = createClassLoader(testClass, instrumentationConfig, runtimeSdk)
        return JUnit5RobolectricAndroidSandbox(
            runtimeSdk,
            compileSdk,
            resourcesMode,
            apkLoader,
            testEnvironmentSpec,
            sdkSandboxClassLoader,
            shadowProviders,
            sqLiteMode,
        )
    }

    private fun createClassLoader(
        testClass: Class<*>,
        instrumentationConfig: InstrumentationConfiguration,
        runtimeSdk: Sdk,
    ): SdkSandboxClassLoader {
        val outerMostDeclaringClassName = testClass.outerMostDeclaringClass().name
        return classLoaderCache.getOrPut(outerMostDeclaringClassName) {
            logger.debug {
                "Create ${SdkSandboxClassLoader::class.simpleName}[$runtimeSdk] instance for ${
                    outerMostDeclaringClassName.substringAfterLast('.')
                }"
            }
            SdkSandboxClassLoader(instrumentationConfig, runtimeSdk, classInstrumentor)
        }
    }

    private companion object {
        private val classLoaderCache = ConcurrentHashMap()
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy