tmurakami/dexopener

Dexopener not working

Closed this issue · 5 comments

after applying this lib to my project i still get the error below

Mockito can only mock non-private & non-final classes.
If you're not sure why you're getting this error, please report to the mailing list.



IMPORTANT INFORMATION FOR ANDROID USERS:

The regular Byte Buddy mock makers cannot generate code on an Android VM!
To resolve this, please use the 'mockito-android' dependency for your application:
http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22mockito-android%22%20g%3A%22org.mockito%22

Java               : 0.9
JVM vendor name    : The Android Project
JVM vendor version : 2.1.0
JVM name           : Dalvik
JVM version        : 0.9
JVM info           : null
OS name            : Linux
OS version         : 4.4.116-g8a6cc9c6abe9

Here is my custom test runner

class CustomTestRunner: AndroidJUnitRunner() {

    override fun newApplication(cl: ClassLoader?, className: String?, context: Context?): Application {
        DexOpener.install(this)
        return super.newApplication(cl, className, context)
    }

}

Here is my build gradle

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

apply plugin: 'kotlin-kapt'

apply plugin: 'kotlin-allopen'

android {
    compileSdkVersion 28
    testOptions.unitTests.includeAndroidResources = true
    defaultConfig {
        applicationId "com.myproject"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
//        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        testInstrumentationRunner 'com.myproject.CustomTestRunner'
        testInstrumentationRunnerArguments clearPackageData: 'true'

    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug{

        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    useLibrary 'android.test.runner'

    useLibrary 'android.test.base'
    useLibrary 'android.test.mock'

}

repositories {
    maven { url 'https://jitpack.io' }
}

allOpen {
    // allows mocking for classes w/o directly opening them for release builds
    annotation 'com.myproject.test.OpenClass'
}

dependencies {
    def lifecycle_version = "2.0.0"
    def mockito = "2.21.0"
    def mockito_android = "2.23.4"

    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.recyclerview:recyclerview:1.0.0'

    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

    //network lib
    implementation 'com.squareup.retrofit2:retrofit:2.5.0'
    implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2'

    //Android architecture libs
    implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"

    implementation "com.squareup.okhttp3:logging-interceptor:3.11.0"

    // Koin for Android
    implementation 'org.koin:koin-android:1.0.2'
    // Koin for Lifecycle scoping
    implementation 'org.koin:koin-androidx-scope:1.0.2'
    //Koin for Android Architecture ViewModel
    implementation 'org.koin:koin-androidx-viewmodel:1.0.2'

    implementation 'com.google.code.gson:gson:2.8.5'
    implementation 'com.squareup.retrofit2:converter-gson:2.5.0'

    //room db
    kapt 'androidx.room:room-compiler:2.1.0-alpha03'
    implementation 'androidx.room:room-runtime:2.1.0-alpha03'
    implementation 'androidx.room:room-testing:2.1.0-alpha03'

    //android instrumental test
    androidTestImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
    androidTestImplementation 'androidx.test.ext:junit:1.1.0'
    androidTestImplementation 'androidx.test.ext:truth:1.1.0'
    androidTestImplementation 'androidx.test:core:1.1.0'
    androidTestImplementation 'androidx.test:runner:1.1.1'
    androidTestImplementation('androidx.arch.core:core-testing:2.0.0') {
        exclude group: 'org.mockito:mockito-core'
    }
    androidTestUtil 'androidx.test:orchestrator:1.1.1'
    androidTestImplementation 'com.github.tmurakami:dexopener:2.0.0'

    androidTestImplementation 'com.jraska.livedata:testing-ktx:0.6.0'
    androidTestImplementation 'com.jraska.livedata:testing:0.6.0'

//    androidTestImplementation "org.mockito:mockito-core:$mockito"
    androidTestImplementation"org.mockito:mockito-android:$mockito_android"
//        exclude group: 'org.mockito'
//    }

    androidTestImplementation('org.koin:koin-test:1.0.2') {
        exclude group: 'org.mockito'
    }

//    androidTestImplementation 'com.linkedin.dexmaker:dexmaker-mockito:2.21.0'

//    androidTestImplementation ("org.mockito:mockito-inline:$mockito"){
//        exclude group: 'org.mockito'
//    }

    //unit test
    testImplementation 'junit:junit:4.12'
    testImplementation "org.mockito:mockito-core:$mockito"
    testImplementation "org.mockito:mockito-android:$mockito"
    testImplementation "org.mockito:mockito-inline:$mockito"
    testImplementation 'org.koin:koin-test:1.0.2'
    testImplementation 'androidx.test.ext:junit:1.1.0'
    testImplementation 'androidx.arch.core:core-testing:2.0.0'
    testImplementation 'com.jraska.livedata:testing-ktx:0.6.0'
    testImplementation 'com.jraska.livedata:testing:0.6.0'
    testImplementation 'androidx.test.ext:truth:1.1.0'
}

Could you share your reproducible project?

Thank you. I'll look into it.

I ran your project and faced the following error:

$ ./gradlew cAT

[snip]

com.richards.jonathan.postapp.UseCaseUnitTests > testGetPostList[Nexus_5_API_21(AVD) - 5.0.2] �[31mFAILED �[0m
	org.koin.error.AlreadyStartedException: Koin is already started. Run startKoin only once or use loadKoinModules
	at org.koin.standalone.StandAloneContext.startKoin(StandAloneContext.kt:55)
11:11:50 V/InstrumentationResultParser: INSTRUMENTATION_STATUS_CODE: -2
11:11:50 V/InstrumentationResultParser: INSTRUMENTATION_STATUS: numtests=4
11:11:50 V/InstrumentationResultParser: INSTRUMENTATION_STATUS: stream=
11:11:50 V/InstrumentationResultParser: INSTRUMENTATION_STATUS: id=AndroidJUnitRunner
11:11:50 V/InstrumentationResultParser: INSTRUMENTATION_STATUS: test=testGetCommentCount
11:11:50 V/InstrumentationResultParser: INSTRUMENTATION_STATUS: class=com.richards.jonathan.postapp.UseCaseUnitTests
11:11:50 V/InstrumentationResultParser: INSTRUMENTATION_STATUS: current=3
11:11:50 V/InstrumentationResultParser: INSTRUMENTATION_STATUS_CODE: 1
11:11:51 V/InstrumentationResultParser: INSTRUMENTATION_STATUS: numtests=4
11:11:51 V/InstrumentationResultParser: INSTRUMENTATION_STATUS: stream=
11:11:51 V/InstrumentationResultParser: Error in testGetCommentCount(com.richards.jonathan.postapp.UseCaseUnitTests):
11:11:51 V/InstrumentationResultParser: org.koin.error.BeanInstanceCreationException: Can't create definition for 'Single [name='NetworkControllerContract',class='com.richards.jonathan.postapp.data.network.contract.NetworkControllerContract']' due to error :
11:11:51 V/InstrumentationResultParser: 
11:11:51 V/InstrumentationResultParser: Mockito cannot mock this class: interface com.richards.jonathan.postapp.data.network.contract.NetworkControllerContract.
11:11:51 V/InstrumentationResultParser: 
11:11:51 V/InstrumentationResultParser: Mockito can only mock non-private & non-final classes.
11:11:51 V/InstrumentationResultParser: If you're not sure why you're getting this error, please report to the mailing list.
11:11:51 V/InstrumentationResultParser: 
11:11:51 V/InstrumentationResultParser: 
11:11:51 V/InstrumentationResultParser: 
11:11:51 V/InstrumentationResultParser: IMPORTANT INFORMATION FOR ANDROID USERS:
11:11:51 V/InstrumentationResultParser: 
11:11:51 V/InstrumentationResultParser: The regular Byte Buddy mock makers cannot generate code on an Android VM!
11:11:51 V/InstrumentationResultParser: To resolve this, please use the 'mockito-android' dependency for your application:
11:11:51 V/InstrumentationResultParser: http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22mockito-android%22%20g%3A%22org.mockito%22
11:11:51 V/InstrumentationResultParser: 
11:11:51 V/InstrumentationResultParser: Java               : 0.9
11:11:51 V/InstrumentationResultParser: JVM vendor name    : The Android Project
11:11:51 V/InstrumentationResultParser: JVM vendor version : 2.1.0
11:11:51 V/InstrumentationResultParser: JVM name           : Dalvik
11:11:51 V/InstrumentationResultParser: JVM version        : 0.9
11:11:51 V/InstrumentationResultParser: JVM info           : null
11:11:51 V/InstrumentationResultParser: OS name            : Linux
11:11:51 V/InstrumentationResultParser: OS version         : 3.10.0+
11:11:51 V/InstrumentationResultParser: 
11:11:51 V/InstrumentationResultParser: 
11:11:51 V/InstrumentationResultParser: Underlying exception : org.mockito.exceptions.base.MockitoException:
11:11:51 V/InstrumentationResultParser: Could not look up implicit location for storing generated classes
11:11:51 V/InstrumentationResultParser: 
11:11:51 V/InstrumentationResultParser: You can configure an explicit location by setting the system property
11:11:51 V/InstrumentationResultParser: 'org.mockito.android.target' to a folder for storing generated class files
11:11:51 V/InstrumentationResultParser: This location must be in private scope for most API versions, for example:
11:11:51 V/InstrumentationResultParser: 
11:11:51 V/InstrumentationResultParser: MyActivity.this.getDir("target", Context.MODE_PRIVATE)
11:11:51 V/InstrumentationResultParser: or
11:11:51 V/InstrumentationResultParser: getInstrumentation().getTargetContext().getCacheDir().getPath()

[snip]

It is the Mockito bug.
mockito/mockito#1472

Add the following line after DexOpener#install in your AndroidJUnitRunner.

System.setProperty("org.mockito.android.target", context!!.cacheDir.absolutePath)

O ok cool thanks that worked