web-dev-qa-db-fra.com

Appels de méthode moqueurs utilisant power mockito - org.powermock.api.mockito.ClassNotPreparedException

J'ai une classe de chargeur d'images et j'ai besoin de tester certaines méthodes statiques. Comme Mockito ne prend pas en charge les méthodes statiques, je suis passé à Power Mockito. Mais la méthode statique que je teste a un appel de méthode 

 Base64.encodeToString(byteArray, Base64.DEFAULT);

Pour me moquer de cela, j'utilise mockStatic comme ci-dessous avec l'annotation @PrepareForTest.

 PowerMockito.mockStatic(Base64.class);

Mais le studio Android me renvoie toujours une erreur comme ci-dessous.

org.powermock.api.mockito.ClassNotPreparedException: La classe Android.util.Base64 non préparé pour le test. Pour préparer cette classe, ajoutez classe à l'annotation '@PrepareForTest'.

Ci-dessous, mon code complet.

Code à tester:

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);
}

Code de la classe de test

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());
}

}

Dépendances Gradle

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'
18
Ajith Memana

Réponse courte tu ne peux pas. Ici du FAQ :

Quelles sont les limites de Mockito

  • Ne peut pas se moquer des classes finales
  • Impossible de se moquer des méthodes statiques
  • Impossible de se moquer des méthodes finales - leur comportement réel est exécuté sans aucune exception. Mockito ne peut pas vous avertir de vous moquer des méthodes finales alors Soyez vigilant.

Informations complémentaires sur cette limitation:

Puis-je me moquer des méthodes statiques?

Non. Mockito préfère l'orientation des objets et l'injection de dépendance par rapport à Code de procédure statique difficile à comprendre et à modifier. Si vous traiter avec effrayant code hérité, vous pouvez utiliser JMockit ou Powermock pour se moquer méthodes statiques.

Si vous voulez utiliser PowerMock, essayez comme ceci:

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

EDIT: Dans Mockito 2, il est maintenant possible de se moquer de la classe finale et de la méthode finale . C'est une option opt-in. Vous devez créer le fichier src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker avec le contenu suivant:

mock-maker-inline
10
JEY

En plus de @PrepareForTest, utilisez également extends PowerMockTestCase

Exemple: @PrepareForTest({Base64.class}) public class ImageLoaderTest extends PowerMockTestCase

0
Akshay Thorve