question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Test fails after enabling feature for mocking final classes and methods

See original GitHub issue

I am mocking GoogleSignInAccount with the latest Mockito version:

GoogleSignInAccount mockGoogleAccount = mock(GoogleSignInAccount.class);
    when(mockGoogleAccount.getId()).thenReturn("id");
    when(mockGoogleAccount.getEmail()).thenReturn("email@email.com");
    when(mockGoogleAccount.getFamilyName()).thenReturn("family name");
    when(mockGoogleAccount.getGivenName()).thenReturn("given name");

After enabling mocking of final classes/methods test fails with this error (which is not really helpful):

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'.
For example:
    when(mock.getArticles()).thenReturn(articles);

Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
   Those methods *cannot* be stubbed/verified.
   Mocking methods declared on non-public parent classes is not supported.
2. inside when() you don't call method on mock but on some other object.

	at com.app.profile.data.ProfileRepositoryTest.shouldFailRegisterIfEmailNotRegisteredAndUnknownGenderGoogleAccount(ProfileRepositoryTest.java:870)
	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)

Let me know if you need more details from me.

Issue Analytics

  • State:open
  • Created 6 years ago
  • Reactions:2
  • Comments:17 (12 by maintainers)

github_iconTop GitHub Comments

1reaction
tmurakamicommented, Mar 31, 2017

Add the -noverify option into your app/build.gradle.

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "com.geraltencore.mockitobug"
        minSdkVersion 16
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    testOptions {
        unitTests.all {
            jvmArgs '-noverify'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.0'
    compile 'com.google.android.gms:play-services-auth:10.2.1'
    testCompile 'org.mockito:mockito-core:2.7.19'
    testCompile 'junit:junit:4.12'
}

Then, run ./gradlew clean test.

Here is my Java environment:

openjdk version "1.8.0_121"
OpenJDK Runtime Environment (build 1.8.0_121-8u121-b13-0ubuntu1.16.10.2-b13)
OpenJDK 64-Bit Server VM (build 25.121-b13, mixed mode)

If you run test on Android Studio, set -noverify as VM options in the Run/Debug Configurations dialog.

0reactions
tmurakamicommented, Nov 9, 2017

@ChristianSchwarz, thank you for your information. However, that PR will not solve this issue.

Generally, an Android project has two kinds of tests.

  1. Local Unit Tests (on JVM)
  2. Instrumented Unit Tests (on Android VM)

That PR seems to provide inline mocking feature on Android VM using slicer library.

On the other hand, this problem occurs while running local unit tests, so unfortunately that PR will not help this issue.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to mock a final class with mockito - java - Stack Overflow
Before Mockito can be used for mocking final classes and methods, it needs to be > configured. We need to add a text...
Read more >
Mock Final Classes and Methods with Mockito - Baeldung
Mockito checks the extensions directory for configuration files when it is loaded. This file enables the mocking of final methods and classes.
Read more >
How to Mock Final Classes in Unit Tests | Object Partners
Extracting an interface, making a method not final, etc. are all valid options. However, it is not always practical, the class you need...
Read more >
Mock final classes with Mockito - Igorski
This makes the test fail with the following exception: ... Turning on the Mockito mock-maker-inline feature adds a second MockMaker on the classpath, ......
Read more >
How to Mock Final Classes in PHPUnit - Tomas Votruba
Then use the interface instead of the class in your test: <?php use PHPUnit\Framework\TestCase; final class FinalClassTest extends TestCase { ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found