Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mockito cannot mock this class: FirebaseRemoteConfig #1138

Closed
andersu opened this issue Jun 26, 2017 · 9 comments
Closed

Mockito cannot mock this class: FirebaseRemoteConfig #1138

andersu opened this issue Jun 26, 2017 · 9 comments
Labels

Comments

@andersu
Copy link

andersu commented Jun 26, 2017

I'm using mockito 2.8.9 with mock-maker-inline and run into the following problem.

Looks to be closely related to #1078
I tried the -noverify JVM argument suggested on that issue, but then it seems like Mockito's verify method does not work.

verify(addressService).saveSelectedAddress(any(Address::class.java))

Stacktrace without -noverify:

org.mockito.exceptions.base.MockitoException:
Mockito cannot mock this class: class com.google.firebase.remoteconfig.FirebaseRemoteConfig.

If you're not sure why you're getting this error, please report to the mailing list.


Java               : 1.8
JVM vendor name    : JetBrains s.r.o
JVM vendor version : 25.112-b06
JVM name           : OpenJDK 64-Bit Server VM
JVM version        : 1.8.0_112-release-b06
JVM info           : mixed mode
OS name            : Mac OS X
OS version         : 10.12.5`


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 : org.mockito.exceptions.base.MockitoException: Could not modify all classes [class com.google.firebase.remoteconfig.FirebaseRemoteConfig]
	at br.project.pine.BaseTest.init(BaseTest.java:9)
	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.RunBefores.evaluate(RunBefores.java:24)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	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.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)
Caused by: org.mockito.exceptions.base.MockitoException: Could not modify all classes [class com.google.firebase.remoteconfig.FirebaseRemoteConfig]
	at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:138)
	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)
	... 23 more
Caused by: java.lang.IllegalStateException: 
Byte Buddy could not instrument all classes within the mock's type hierarchy
This problem should never occur for javac-compiled classes. This problem has been observed for classes that are:
 - Compiled by older versions of scalac
 - Classes that are part of the Android distribution
	at org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.triggerRetransformation(InlineBytecodeGenerator.java:120)
	at org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.mockClass(InlineBytecodeGenerator.java:97)
	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)
	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:63)
	at org.mockito.Mockito.mock(Mockito.java:1729)
	at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:33)
	at org.mockito.internal.configuration.MockAnnotationProcessor.process(MockAnnotationProcessor.java:16)
	at org.mockito.internal.configuration.IndependentAnnotationEngine.createMockFor(IndependentAnnotationEngine.java:38)
	at org.mockito.internal.configuration.IndependentAnnotationEngine.process(IndependentAnnotationEngine.java:62)
	at org.mockito.internal.configuration.InjectingAnnotationEngine.processIndependentAnnotations(InjectingAnnotationEngine.java:57)
	at org.mockito.internal.configuration.InjectingAnnotationEngine.process(InjectingAnnotationEngine.java:41)
	at org.mockito.MockitoAnnotations.initMocks(MockitoAnnotations.java:69)
	... 23 more
Caused by: java.lang.IllegalStateException: Inconsistent frame length for public void com.google.firebase.remoteconfig.FirebaseRemoteConfig.setDefaults(int,java.lang.String): 1
	at net.bytebuddy.asm.Advice$StackMapFrameHandler$Default.translateFrame(Advice.java:1187)
	at net.bytebuddy.asm.Advice$StackMapFrameHandler$Default.translateFrame(Advice.java:1141)
	at net.bytebuddy.asm.Advice$AdviceVisitor.visitFrame(Advice.java:6636)
	at net.bytebuddy.jar.asm.ClassReader.a(Unknown Source)
	at net.bytebuddy.jar.asm.ClassReader.b(Unknown Source)
	at net.bytebuddy.jar.asm.ClassReader.accept(Unknown Source)
	at net.bytebuddy.jar.asm.ClassReader.accept(Unknown Source)
	at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForInlining.create(TypeWriter.java:2910)
	at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:1628)
	at net.bytebuddy.dynamic.scaffold.inline.RedefinitionDynamicTypeBuilder.make(RedefinitionDynamicTypeBuilder.java:171)
	at net.bytebuddy.dynamic.scaffold.inline.AbstractInliningDynamicTypeBuilder.make(AbstractInliningDynamicTypeBuilder.java:92)
	at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:2560)
	at org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.transform(InlineBytecodeGenerator.java:167)
	at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
	at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:428)
	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:117)
	... 43 more

Result with -noverify:

java.lang.IllegalStateException: any(Address::class.java) must not be null
	at br.project.pine.presentation.scenes.mylocation.interactor.MyLocationInteractorImplTest.onCreate_callsAddressService_saveSelectedAddress_withDummyAddressInSaoPaulo_whenLocationUnavailable(MyLocationInteractorImplTest.kt:69)
	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.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	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.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)

When I debug the test I can see that saveSelectedAddress is called with a non-null object, but the test still fails.

@raphw
Copy link
Member

raphw commented Jun 26, 2017

The error is inthe stack trace. Its due to inconsistent stack frames what is typically a result of obfuscation.

@andersu
Copy link
Author

andersu commented Jun 26, 2017

Thanks @raphw. In the other issue you say you filed a bug report at Proguard. Can you give me the link to that so I can follow the progress?

@TimvdLippe
Copy link
Contributor

@andersu https://sourceforge.net/p/proguard/bugs/647/

@tmurakami
Copy link
Contributor

I assume that the Firebase library for Android is obfuscated with the option -dontpreverify.
If so, the only way to solve this problem would be to get the Firebase developers to change their ProGuard configuration.

@andersu, do you use Mockito#any() directly?
Since it returns null, it cannot be applied to functions that do not allow null.
You can use mockito-kotlin or my mockito4k instead.

@Writtscher
Copy link

Writtscher commented Jul 5, 2017

@TimvdLippe Are there any plans to make verifying (using eq(), any()) in kotlin possible? I mean I have no problem with mockito-kotlin but shouldn't it be the long term plan to support kotlin as well without the need for another library?

@TimvdLippe
Copy link
Contributor

@Writtscher Please open a new issue to discuss that issue. Then we can flesh out plans to see what we can do to improve Kotlin support. For now, there is an available solution/workaround, so have to see what the costs and benefits are.

@tillkrempel
Copy link

tillkrempel commented Sep 20, 2018

I have the same problem when trying to mock DatabaseReference for the Firebase Realtime Database, when trying to mock it with mockito-inline on Kotlin. As some of the Firebase Android SDKs are now open source, I investigated there, but it does not seem that the option -dontpreverify is used, as mentioned by @tmurakami.

https://github.com/firebase/firebase-android-sdk/tree/master/firebase-database

the suggested -noverify solution in #1078 does not work for me. When using mockito-core it works, but as all classes are final by default in Kotlin this causes all other tests to fail.

@raphw
Copy link
Member

raphw commented Sep 20, 2018

What Mockito version are you using. Are you getting verification errors? Those should be solved with the latest releases.

@bric3 bric3 added the android label Mar 4, 2019
@TimvdLippe
Copy link
Contributor

Closing per above comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants