Mocking method calls using power mockito - org.powermock.api.mockito.ClassNotPreparedException

40,234

Short answer you can't. Here from the FAQ:

What are the limitations of Mockito

  • Cannot mock final classes
  • Cannot mock static methods
  • Cannot mock final methods - their real behavior is executed without any exception. Mockito cannot warn you about mocking final methods so be vigilant.

Further information about this limitation:

Can I mock static methods?

No. Mockito prefers object orientation and dependency injection over static, procedural code that is hard to understand & change. If you deal with scary legacy code you can use JMockit or Powermock to mock static methods.

If you want to use PowerMock try like this:

@RunWith(PowerMockRunner.class)
@PrepareForTest( { Base64.class })
public class YourTestCase {
    @Test
    public void testStatic() {
        mockStatic(Base64.class);
        when(Base64.encodeToString(argument)).thenReturn("expected result");
    }
}

EDIT: In Mockito 2 it's now possible to mock final Class and final Method. It's an opt-in option. You need to create the file src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker with the following content:

mock-maker-inline

EDIT 2: Since Mockito 3.4.0 its now possible to mock static method too:

try (MockedStatic mocked = mockStatic(Base64.class)) {
    mocked.when(() -> Base64.encodeToString(eq(array), eq(Base64.DEFAULT))).thenReturn("bar");
    assertEquals("bar", Base64.encodeToString(array, Base64.DEFAULT));
    mocked.verify(() -> Base64.encodeToString(any(), anyIn());
}

Furthermore you can directly add as a dependency org.mockito:mockito-inline:+ and avoid manually create the or.mockito.plugins.MockMaker file

Since Mockito 3.5.0 you can also mock object construction.

Share:
40,234
Ajith M A
Author by

Ajith M A

Android developer from India

Updated on January 09, 2022

Comments

  • Ajith M A
    Ajith M A over 2 years

    I have an image loader class and i need to test some static methods in it. Since Mockito does not support static methods i switched to Power Mockito. But the static method i am testing has a method call

     Base64.encodeToString(byteArray, Base64.DEFAULT);
    

    To mock this i am using mockStatic method as below with @PrepareForTest annotation.

     PowerMockito.mockStatic(Base64.class);
    

    But Android studio is returning me still returning me an error as below.

    org.powermock.api.mockito.ClassNotPreparedException: The class android.util.Base64 not prepared for test. To prepare this class, add class to the '@PrepareForTest' annotation.

    Below is my complete code.

    Code to be tested:

    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.util.Base64;
    import android.widget.ImageView;
    
      public static String convertBitmapToBase64(Bitmap imageBitmap, boolean withCompression) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        imageBitmap.compress(Bitmap.CompressFormat.PNG, 120, byteArrayOutputStream);
        byte[] byteArray = byteArrayOutputStream.toByteArray();
        return Base64.encodeToString(byteArray, Base64.DEFAULT);
    }
    

    Test class code

    import android.graphics.Bitmap;
    import android.util.Base64;
    import org.junit.Before;
    import org.junit.runner.RunWith;
    import org.mockito.MockitoAnnotations;
    import org.powermock.api.mockito.PowerMockito;
    import org.powermock.core.classloader.annotations.PrepareForTest;
    import org.powermock.modules.junit4.PowerMockRunner;
    import org.testng.annotations.Test;
    
    @RunWith(PowerMockRunner.class)
    @PrepareForTest({Base64.class})
    public class ImageLoaderTest  {
    @Test
       public void testConvertBitmap(){
        byte[] array = new byte[20];
        PowerMockito.mockStatic(Base64.class);
        PowerMockito.when(Base64.encodeToString(array, Base64.DEFAULT)).thenReturn("asdfghjkl");
        Bitmap mockedBitmap= PowerMockito.mock(Bitmap.class);
        String output = ImageLoaderUtils.convertBitmapToBase64(mockedBitmap);
        assert (!output.isEmpty());
    }
    

    }

    Gradle dependencies

    testCompile 'junit:junit:4.12'
    testCompile 'org.powermock:powermock:1.6.5'
    testCompile 'org.powermock:powermock-module-junit4:1.6.5'
    testCompile 'org.powermock:powermock-api-mockito:1.6.5'