Android : Mockito (2.0.2-beta) - Cannot mock/spy final classes

mockito cannot mock/spy because : - final class
mock gson mockito
cannot mock/spy class java lang string

I am using mockito-all, version: '2.0.2-beta' in an Android Instrumental test to mock PowerManager, which is a final class,

I am getting -

org.mockito.exceptions.base.MockitoException:
Cannot mock/spy class android.os.PowerManager
Mockito cannot mock/spy following:
- final classes
- anonymous classes
- primitive types
at com.crsardar.handson.android.mockito.ExampleInstrumentedTest.useAppContext(ExampleInstrumentedTest.java:38)
at java.lang.reflect.Method.invoke(Native Method)
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.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 android.support.test.runner.AndroidJUnit4.run(AndroidJUnit4.java:101)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
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 org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:384)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1932)

My app's build.gradle is as follows -

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.crsardar.handson.android.mockito"
        minSdkVersion 25
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    configurations.all {
        resolutionStrategy {
            force 'com.android.support:support-annotations:26.1.0'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation group: 'org.mockito', name: 'mockito-all', version: '2.0.2-beta'
}

My instrumental test case is as follows -

package com.crsardar.handson.android.mockito;

import android.content.Context;
import android.os.PowerManager;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

/**
 * Instrumented test, which will execute on an Android device.
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {

    private Context mockedContext = null;

    @Test
    public void useAppContext() {

        PowerManager mockedPowerManager = mock(PowerManager.class);
        System.out.println("Before mockedPowerManager = " + mockedPowerManager.hashCode());

        mockedContext = mock(Context.class);

        when(mockedContext.getSystemService(Context.POWER_SERVICE)).thenReturn(mockedPowerManager);

        System.out.println("After mockedPowerManager = " + mockedContext.getSystemService(Context.POWER_SERVICE).hashCode());
    }
}

None of the existing post in StackOverflow were helpful, any help is really appreciated


Can use ShadowPowerManager by following way:

  private PowerManager powerManager;
  private ShadowPowerManager shadowPowerManager;

  @Before
  public void before() {
    powerManager =  (PowerManager)ApplicationProvider.getApplicationContext().getSystemService(Context.POWER_SERVICE);
    shadowPowerManager = shadowOf(powerManager);
    shadowPowerManager.setIsScreenOn(false);
  }

Mockito (Mockito 2.0.2-beta API), (new) Spying or mocking abstract classes (Since 1.10.12) The consequence is that you cannot use anyObject() , eq() methods outside of Mockito doesn't mock final methods so the bottom line is: when you spy on real objects + For example, it is now possible to use Mockito for Android testing with a help of dexmaker. Mockito cannot mock/spy because : – final class We’re no longer limited to mock anonymous classes or primitive types, but it’s not the same for final classes.


After researching more I found - As of this version of Mockito, it is NOT possible.

Mockito (Mockito 2.20.0 API), 2.1.0-beta.126 2.1.0-beta.125 2.1.0-beta.124 2.1.0-beta.123 2.1.0-beta.122 2.1​.0-beta.121 Be aware that you cannot use the inline mock maker on Android due to //mock creation List mockedList = mock(List.class); //using mock object Mockito doesn't mock final methods so the bottom line is: when you spy on real  Secondly and most importantly, Mockito 2.10 provided a new update where we can mock the final classes. Let's talk about it in detail.In the project, under src->test folder create a resources directory. Inside it create a new directory called mockito-extensions . Inside the mockito-extensions directory we create a text file called


Well, I tried to run with local jvm,

@RunWith(PowerMockRunner.class)
@PrepareForTest(PowerManager.class)
public class ExampleUnitTest2 {

    @Mock
    private Context mContext;

    @Mock
    private PowerManager mPowerManager;


    @Before
    public void setup(){
        MockitoAnnotations.initMocks(this);
        Mockito.when(mContext.getSystemService(Context.POWER_SERVICE)).thenReturn(mPowerManager);
        System.out.println("After mockedPowerManager = " + mContext.getSystemService(Context.POWER_SERVICE).hashCode());

    }
}

Here's the output,

After mockedPowerManager = 793319856
After mockedPowerManager = 1340086275

What's new in Mockito 2, A landing page for information about Mockito framework, a mocking framework for unit tests written in Java. Tasty mocking framework for unit tests in Java mock creation List mockedList = mock(List.class); // using mock object - it does not inject mocks/spies fields annotated with @Spy or @Mock; verify() : to check​  Recently I started tests for my complete project with Kotlin and I came across the “Mockito cannot mock/spy because : final class” problem because by default all classes in Kotlin are final. This is not a new problem and a lot of people from the community have posted various blogs and answers regarding this problem (as shown below).


Mockito framework site, Mockito Mock Static Method, PowerMock Mockito tutorial, PowerMock JUnit, Mockito Spy · 8. Since static method belongs to the class, there is no way in Mockito to mock static <powermock.version>2.0.0-beta.5</powermock.version​> TestNG Test Fails when executed from command line with message "Cannot use  Cannot mock/spy class com.ExternalpackagePath.Externalclass . Mockito cannot mock/spy because : final class; I know that this question has already been asked (How to mock a final class with mockito, Mock objects calling final classes static methods with Mockito), but I didn't find the answer I'm looking for. Here is an extract of my code :


Mockito Mock Static Method - PowerMock, Я использую mockito-all , version: '2.0.2-beta' в инструментальном тесте Android для PowerManager Mockito cannot mock/spy following: - final classes​  In this short article, we'll focus on how to mock final classes and methods – using Mockito. As with other articles focused on the Mockito framework (like Mockito Verify , Mockito When/Then , and Mockito's Mock Methods ) we'll use the MyList class shown below as the collaborator in test cases.


Android: Mockito (2.0.2-бета), Most of the mocking frameworks in Java, including Mockito, cannot mock static methods or final classes. If we come across a version >2.0.5-beta</ version > Since SomeSystem is our SUT, we will create a spy object of it so that later we can stub some of its behavior. Now let's 7. Android UI Design  @EvgeniPetrov if your original method is still being called it's probably because your original method is final. Mockito doesn't mock final methods, and cannot warn you about the mocking of final methods. – MarcG Dec 8 '14 at 21:01