Hot questions for Using Mockito in dexmaker

Hot questions for Using Mockito in dexmaker

Question:

So I have a Database class that has a dependency that extends SQLOpenHelper and I am testing using Android instrumented tests and Mockito to mock dependencies. We are noticing that Mockito isn't actually mocking the implementations when doing Mockito.mock(class) instead the actual code is running and throwing null pointer exceptions as we would expect. On API 19 devices the tests run as expected and the mocks work correctly.

Does anyone have any suggestions or things to try? I've tried real devices and emulators with similar results. Could this be a Mockito issue, or a dex-maker issue? I haven't found any information while searching for it.

After some more testing any class I mock with Mockito actually just uses the implementation. Here are my dependencies

androidTestCompile 'org.mockito:mockito-core:1.10.19'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'

Note: This is also in a library module if that makes any difference.


Answer:

So getting rid of our old Mockito dependencies and dexmaker and using the new: Mockito-android

Fixed our issues

Question:

I am trying to incorporate Powermock as a dependency for my Android tests using the following build.gradle configuration:

dependencies{
    compile 'com.android.support:appcompat-v7:21.0.+'
    androidTestCompile('org.mockito:mockito-core:1.9.5')
    androidTestCompile('com.google.dexmaker:dexmaker:1.2')
    androidTestCompile('com.google.dexmaker:dexmaker-mockito:1.2')
    androidTestCompile('org.powermock:powermock-module-junit4:1.5.5') {
        exclude module: 'junit'
    }
    androidTestCompile('org.powermock:powermock-api-mockito:1.5.5') {
        exclude module: 'mockito-all'
    }
}

However, the compiler is complaining that

Error:Gradle: Execution failed for task ':app:packageDebugTest'.
> Duplicate files copied in APK mockito-extensions/org.mockito.plugins.MockMaker
    File 1: ~/.gradle/caches/modules-2/files-2.1/com.google.dexmaker/dexmaker-mockito/1.2/b99884a4c6ef6335ba376f79aa79632b2421c17c/dexmaker-mockito-1.2.jar
    File 2: ~/.gradle/caches/modules-2/files-2.1/com.google.dexmaker/dexmaker-mockito/1.2/b99884a4c6ef6335ba376f79aa79632b2421c17c/dexmaker-mockito-1.2.jar

Looking into the jar structure, I noticed that both Dexmaker and Powermock declare a MockMaker in mockito-extensions

What is a MockMaker? How do they differ? And the most important question: Is it possible to get Powermock to work nicely with Dexmaker?

Thanks in advance. Any help would be greatly appreciated.


Answer:

MockMaker is a glue module that integrates dexmaker with Mockito. It does what's necessary for Mockito to generate concrete classes with Dalvik .dex files instead of JVM .class files.

It's possible that Powermock will work with Dexmaker, but it's unlikely advanced Powermock features will work. In particular, Powermock advertises this:

PowerMock uses a custom classloader and bytecode manipulation to enable mocking of static methods, constructors, final classes and methods, private methods, removal of static initializers and more.

That custom class loader is unlikely to work on dalvikvm.

Question:

I have some android-tests that crash hard when run on android versions under 4.4 / Kitkat.

These are the libraries I have in my build.gradle

androidTestCompile 'org.mockito:mockito-core:1.9.5'
androidTestCompile 'com.google.dexmaker:dexmaker:1.1'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.1'

The tests run just as expected on android version 4.4, although I needed to add some hints to tell Dexmaker where to put its cache:

System.setProperty("dexmaker.dexcache", getInstrumentation().getContext().getCacheDir().getPath());

Here is the logcat output from the device:

D/dalvikvm( 1712): GC_FOR_ALLOC freed 479K, 19% free 2532K/3124K, paused 3ms, total 3ms
D/dalvikvm( 1712): GC_CONCURRENT freed 427K, 18% free 2595K/3136K, paused 1ms+0ms, total 3ms
D/dalvikvm( 1712): GC_CONCURRENT freed 311K, 16% free 2686K/3188K, paused 3ms+0ms, total 4ms
D/dalvikvm( 1712): GC_FOR_ALLOC freed 127K, 11% free 2852K/3188K, paused 1ms, total 1ms
D/dalvikvm( 1712): GC_FOR_ALLOC freed 123K, 7% free 3239K/3476K, paused 4ms, total 4ms
D/dalvikvm( 1712): GC_CONCURRENT freed 53K, 6% free 3276K/3476K, paused 2ms+0ms, total 10ms
D/dalvikvm( 1712): DexOpt: --- BEGIN 'Generated-1815896169.jar' (bootstrap=0) ---
D/dalvikvm( 1728): DexOpt: load 1ms, verify+opt 0ms, 82180 bytes
D/dalvikvm( 1712): DexOpt: --- END 'Generated-1815896169.jar' (success) ---
D/dalvikvm( 1712): DEX prep '/data/data/my.app.identifier/cache/Generated-1815896169.jar': unzip in 0ms, rewrite 15ms
I/dalvikvm( 1712): DexOpt: illegal method access (call Ljava/lang/Object;.internalClone (Ljava/lang/Cloneable;)Ljava/lang/Object; from LBackendAddressServiceImpl_Proxy;)
I/dalvikvm( 1712): Could not find method my.app.identifier.backend.BackendAddressServiceImpl.internalClone, referenced from method BackendAddressServiceImpl_Proxy.internalClone
W/dalvikvm( 1712): VFY: unable to resolve virtual method 50: Lmy/app/identifier/backend/BackendAddressServiceImpl;.internalClone (Ljava/lang/Cloneable;)Ljava/lang/Object;
D/dalvikvm( 1712): VFY: replacing opcode 0x6f at 0x0019
I/dalvikvm( 1712): DexOpt: illegal method access (call Ljava/lang/Object;.internalClone (Ljava/lang/Cloneable;)Ljava/lang/Object; from LBackendAddressServiceImpl_Proxy;)
I/dalvikvm( 1712): Could not find method my.app.identifier.backend.BackendAddressServiceImpl.internalClone, referenced from method BackendAddressServiceImpl_Proxy.super$internalClone$java_lang_Object
W/dalvikvm( 1712): VFY: unable to resoldlve virtual method 50: Lmy/app/identifier/backend/BackendAddressServiceImpl;.internalClone (Ljava/lang/Cloneable;)Ljava/lang/Object;
D/dalvikvm( 1712): VFY: replacing opcode 0x6f at 0x0000
D/dalvikvm( 1712): GC_FOR_ALLOC freed 652K, 20% free 3138K/3904K, paused 4ms, total 4ms
D/dalvikvm( 1712): DexOpt: --- BEGIN 'Generated1066861752.jar' (bootstrap=0) ---
D/dalvikvm( 1712): GC_CONCURRENT freed 44K, 21% free 3103K/3904K, paused 0ms+1ms, total 2ms
D/dalvikvm( 1729): DexOpt: load 0ms, verify+opt 0ms, 81004 bytes
D/dalvikvm( 1712): DexOpt: --- END 'Generated1066861752.jar' (success) ---
D/dalvikvm( 1712): DEX prep '/data/data/my.app.identifier/cache/Generated1066861752.jar': unzip in 0ms, rewrite 13ms
I/dalvikvm( 1712): DexOpt: illegal method access (call Ljava/lang/Object;.internalClone (Ljava/lang/Cloneable;)Ljava/lang/Object; from LAppConfigServiceImpl_Proxy;)
I/dalvikvm( 1712): Could not find method my.app.identifier.config.AppConfigServiceImpl.internalClone, referenced from method AppConfigServiceImpl_Proxy.internalClone
W/dalvikvm( 1712): VFY: unable to resolve virtual method 17: Lmy/app/identifier/config/AppConfigServiceImpl;.internalClone (Ljava/lang/Cloneable;)Ljava/lang/Object;
D/dalvikvm( 1712): VFY: replacing opcode 0x6f at 0x0019
I/dalvikvm( 1712): DexOpt: illegal method access (call Ljava/lang/Object;.internalClone (Ljava/lang/Cloneable;)Ljava/lang/Object; from LAppConfigServiceImpl_Proxy;)
I/dalvikvm( 1712): Could not find method my.app.identifier.config.AppConfigServiceImpl.internalClone, referenced from method AppConfigServiceImpl_Proxy.super$internalClone$java_lang_Object
W/dalvikvm( 1712): VFY: unable to resolve virtual method 17: Lmy/app/identifier/config/AppConfigServiceImpl;.internalClone (Ljava/lang/Cloneable;)Ljava/lang/Object;
D/dalvikvm( 1712): VFY: replacing opcode 0x6f at 0x0000
D/dalvikvm( 1712): GC_CONCURRENT freed 536K, 22% free 3078K/3904K, paused 1ms+1ms, total 7ms
D/dalvikvm( 1712): WAIT_FOR_CONCURRENT_GC blocked 3ms
D/dalvikvm( 1712): GC_FOR_ALLOC freed 492K, 21% free 3098K/3904K, paused 2ms, total 2ms
D/dalvikvm( 1712): GC_FOR_ALLOC freed 468K, 20% free 3142K/3904K, paused 2ms, total 2ms
D/dalvikvm( 1712): GC_CONCURRENT freed 247K, 19% free 3174K/3904K, paused 2ms+0ms, total 4ms
F/libc    ( 1712): Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1), thread 1725 (ationTestRunner)
I/DEBUG   (  109): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG   (  109): Build fingerprint: 'generic/vbox86p/vbox86p:4.2.2/JDQ39E/eng.buildbot.20140523.235904:userdebug/test-keys'
I/DEBUG   (  109): Revision: '0'
I/DEBUG   (  109): pid: 1712, tid: 1725, name: ationTestRunner  >>> my.app.identifier 
I/DEBUG   (  109): 
I/DEBUG   (  109): stack:
I/DEBUG   (  109):          98c5bba0  00000000  
I/DEBUG   (  109):          98c5bba4  00000000  
I/DEBUG   (  109):          98c5bba8  00000000  
I/DEBUG   (  109):          98c5bbac  00000000  
I/DEBUG   (  109):          98c5bbb0  00000000  
I/DEBUG   (  109):          98c5bbb4  00000000  
I/DEBUG   (  109):          98c5bbb8  00000000  
I/DEBUG   (  109):          98c5bbbc  00000000  
I/DEBUG   (  109):          98c5bbc0  00000000  
I/DEBUG   (  109):          98c5bbc4  00000000  
I/DEBUG   (  109):          98c5bbc8  00000000  
I/DEBUG   (  109):          98c5bbcc  00000000  
I/DEBUG   (  109):          98c5bbd0  00000000  
I/DEBUG   (  109):          98c5bbd4  00000000  
I/DEBUG   (  109):          98c5bbd8  00000000  
I/DEBUG   (  109):          98c5bbdc  00000000  
I/DEBUG   (  109):     #00  98c5bbe0  a652fb68  /dev/ashmem/dalvik-heap (deleted)
I/DEBUG   (  109):          98c5bbe4  a6487fe8  /dev/ashmem/dalvik-heap (deleted)
I/DEBUG   (  109):          98c5bbe8  a647f1c0  /dev/ashmem/dalvik-heap (deleted)
I/DEBUG   (  109):          98c5bbec  b66af3d1  /system/lib/libdvm.so (dvmRemoveFromReferenceTable(ReferenceTable*, Object**, Object*)+33)
I/DEBUG   (  109):          98c5bbf0  b6752ca0  /system/lib/libdvm.so
I/DEBUG   (  109):          98c5bbf4  b6751ff4  /system/lib/libdvm.so
I/DEBUG   (  109):          98c5bbf8  00000000  
I/DEBUG   (  109):          98c5bbfc  b66b3fd4  /system/lib/libdvm.so (dvmThreadSelf()+36)
I/DEBUG   (  109):          98c5bc00  00000007  
I/DEBUG   (  109):          98c5bc04  a652fc08  /dev/ashmem/dalvik-heap (deleted)
I/DEBUG   (  109):          98c5bc08  a647f198  /dev/ashmem/dalvik-heap (deleted)
I/DEBUG   (  109):          98c5bc0c  b6751ff4  /system/lib/libdvm.so
I/DEBUG   (  109):          98c5bc10  b7d30a28  [heap]
I/DEBUG   (  109):          98c5bc14  a647f180  /dev/ashmem/dalvik-heap (deleted)
I/DEBUG   (  109):          98c5bc18  98c5bcb8  [stack:1725]
I/DEBUG   (  109):          98c5bc1c  b66ba5b7  /system/lib/libdvm.so (dvmReleaseTrackedAlloc+71)
I/DEBUG   (  109):          ........  ........
I/DEBUG   (  109):     #01  98c5bcc0  b7d30a28  [heap]
I/DEBUG   (  109):          98c5bcc4  00000000  
I/DEBUG   (  109):          98c5bcc8  00000000  
I/DEBUG   (  109):          98c5bccc  00000000  
I/DEBUG   (  109):          98c5bcd0  00000000  
I/DEBUG   (  109):          98c5bcd4  b6751ff4  /system/lib/libdvm.so
I/DEBUG   (  109):          98c5bcd8  b7d30a28  [heap]
I/DEBUG   (  109):          98c5bcdc  b665bd72  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+178)
I/DEBUG   (  109):          98c5bce0  b7d30a28  [heap]
I/DEBUG   (  109):          98c5bce4  00000000  
I/DEBUG   (  109):          98c5bce8  b7596339  /system/lib/libc.so (pthread_mutex_lock+9)
I/DEBUG   (  109):          98c5bcec  b761eff4  /system/lib/libc.so
I/DEBUG   (  109):          98c5bcf0  b7cf4e98  [heap]
I/DEBUG   (  109):          98c5bcf4  00000018  
I/DEBUG   (  109):          98c5bcf8  b7cf4e68  [heap]
I/DEBUG   (  109):          98c5bcfc  b7596509  /system/lib/libc.so (pthread_mutex_unlock+25)
I/DEBUG   (  109):          ........  ........
I/DEBUG   (  109):     #02  b7d30a30  9f27f620  /dev/ashmem/dalvik-LinearAlloc (deleted)
I/DEBUG   (  109):          b7d30a34  9eee8000  /dev/ashmem/dalvik-aux-structure (deleted)
I/DEBUG   (  109):          b7d30a38  a647f180  /dev/ashmem/dalvik-heap (deleted)
I/DEBUG   (  109):          b7d30a3c  00000000  
I/DEBUG   (  109):          b7d30a40  98c5bc70  [stack:1725]
I/DEBUG   (  109):          b7d30a44  00000000  
I/DEBUG   (  109):          b7d30a48  98c5bd1c  [stack:1725]
I/DEBUG   (  109):          b7d30a4c  0000000a  
I/DEBUG   (  109):          b7d30a50  00000000  
I/DEBUG   (  109):          b7d30a54  b665611c  /system/lib/libdvm.so
I/DEBUG   (  109):          b7d30a58  00000000  
I/DEBUG   (  109):          b7d30a5c  00000000  
I/DEBUG   (  109):          b7d30a60  9edb6670  /system/framework/ext.jar
I/DEBUG   (  109):          b7d30a64  98c5c300  
I/DEBUG   (  109):          b7d30a68  00000000  
I/DEBUG   (  109):          b7d30a6c  00000000  
D/AndroidRuntime( 1704): Shutting down VM
I/ActivityManager(  464): Process my.app.identifier (pid 1712) has died.
W/ActivityManager(  464): Crash of app my.app.identifier running instrumentation ComponentInfo{my.app.identifier.test/android.test.InstrumentationTestRunner}
D/dalvikvm( 1704): GC_CONCURRENT freed 100K, 19% free 462K/568K, paused 0ms+0ms, total 2ms
D/jdwp    ( 1704): Got wake-up signal, bailing out of select
D/dalvikvm( 1704): Debugger has detached; object registry had 1 entries
I/ActivityManager(  464): Force stopping package my.app.identifier appid=10048 user=0
D/Zygote  (  198): Process 1712 terminated by signal (11)
W/ThrottleService(  464): unable to find stats for iface rmnet0

Are there any hints on running Mockito / Dexmaker on "older" android-versions?


Answer:

I am not 100 % if that did it (or something else we changed in the meantime) but with Dexmaker 1.2 this seems to be fixed.