Cannot mock Google Analytics Tracker class with Inline Mocks
See original GitHub issueGreetings, I updated Mockito to 2.7.16 to use inline mocks for the seriously awesome feature to mock finals (thank you btw!) but found that the Google Analytics Tracker class wasn’t mocking, where it was before without issue.
I found this post on the Mockito forum with the same problem, but I don’t think the original reporter ever brought the issue to here.
I created a repo that can be used to reproduce the issue. You’ll need Android Studio to be able to run it. The ExampleUnitTest class just tries to mock the com.google.android.gms.analytics.Tracker class and it fails right away. Here’s the stack trace of that failure:
org.mockito.exceptions.base.MockitoException:
Mockito cannot mock this class: class com.google.android.gms.analytics.Tracker.
If you're not sure why you're getting this error, please report to the mailing list.
Java : 1.8
JVM vendor name : Oracle Corporation
JVM vendor version : 25.74-b02
JVM name : Java HotSpot(TM) 64-Bit Server VM
JVM version : 1.8.0_74-b02
JVM info : mixed mode
OS name : Windows 10
OS version : 10.0
You are seeing this disclaimer because Mockito is configured to create inlined mocks.
You can learn about inline mocks and their limitations under item #39 of the Mockito class javadoc.
Underlying exception : java.lang.IllegalArgumentException: Could not create type
at com.test.mockitoanalyticstrackerbug.ExampleUnitTest.watchTrackerFailToBeMockedTest(ExampleUnitTest.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:487)
at org.robolectric.internal.SandboxTestRunner$2.evaluate(SandboxTestRunner.java:209)
at org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:109)
at org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:36)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.robolectric.internal.SandboxTestRunner$1.evaluate(SandboxTestRunner.java:63)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.lang.IllegalArgumentException: Could not create type
at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:140)
at net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:346)
at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:161)
at net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:355)
at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator.mockClass(TypeCachingBytecodeGenerator.java:32)
at org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.createMockType(InlineByteBuddyMockMaker.java:201)
at org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.createMock(InlineByteBuddyMockMaker.java:182)
at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:35)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:65)
at org.mockito.Mockito.mock(Mockito.java:1729)
at org.mockito.Mockito.mock(Mockito.java:1642)
... 30 more
Caused by: java.lang.VerifyError
at sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
at sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:144)
at org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.triggerRetransformation(InlineBytecodeGenerator.java:116)
at org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.mockClass(InlineBytecodeGenerator.java:96)
at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator$1.call(TypeCachingBytecodeGenerator.java:37)
at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator$1.call(TypeCachingBytecodeGenerator.java:34)
at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:138)
... 40 more
There’s no hurry on this fix as we’re not officially supporting analytics yet. I mostly just wanted to bring this to your attention as we’ll need to look into this eventually and I’m sure there will be others trying to mock the Tracker. Let me know if you need more information or if there’s anything I can do to help.
Thanks, Mykaelos
Issue Analytics
- State:
- Created 6 years ago
- Comments:5 (5 by maintainers)
Top GitHub Comments
I think I have this “fixed” as I added an explicit check to Byte Buddy for inconsistent stack map frames. This seems to be a side-effect of using ProGuard in Android which destroys some metainformation in a way that the JVM can still run a method but that makes it practically impossible to instrument a class.
The irony is that this destruction does not obfuscate a thing as it only removes the types of the
this
reference and the parameters such that they can no longer be legally accessed.Byte Buddy does however no longer throw a verifier error but a more descriptive error message.
Closing this per above comment. Feel free to reopen if you are still running into this issue with a recent Mockito version (2.10.0+)