模拟方法调用使用power mockito - org.powermock.api.mockito.ClassNotPreparedException

Aji*_*ana 20 junit android unit-testing mockito powermock

我有一个图像加载器类,我需要在其中测试一些静态方法.由于Mockito不支持静态方法,我改用Power Mockito.但我正在测试的静态方法有一个方法调用

 Base64.encodeToString(byteArray, Base64.DEFAULT);
Run Code Online (Sandbox Code Playgroud)

为了模拟这个,我使用如下的mockStatic方法和@PrepareForTest注释.

 PowerMockito.mockStatic(Base64.class);
Run Code Online (Sandbox Code Playgroud)

但Android工作室正在回复我仍然给我一个错误,如下所示.

org.powermock.api.mockito.ClassNotPreparedException:类android.util.Base64未准备好进行测试.要准备此类,请将类添加到"@PrepareForTest"注释中.

以下是我的完整代码.

要测试的代码:

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);
}
Run Code Online (Sandbox Code Playgroud)

测试类代码

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());
}
Run Code Online (Sandbox Code Playgroud)

}

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'
Run Code Online (Sandbox Code Playgroud)

JEY*_*JEY 11

简短的回答你不能.这里来自FAQ:

Mockito有什么限制

  • 不能模拟最后的课程
  • 无法模拟静态方法
  • 无法模拟最终方法 - 它们的实际行为在没有任何异常的情况下执行.Mockito无法警告你嘲笑最终方法,所以请保持警惕.

有关此限制的更多信息:

我可以模拟静态方法吗?

不,Mockito更喜欢面向对象和依赖注入,而不是那些难以理解和改变的静态程序代码.如果您处理可怕的遗留代码,您可以使用JMockit或Powermock来模拟静态方法.

如果你想使用PowerMock,试试这样:

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

编辑:在Mockito 2中,现在可以模拟最终的Class和final方法.这是一个选择加入的选项.您需要src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker使用以下内容创建文件:

mock-maker-inline
Run Code Online (Sandbox Code Playgroud)

  • 这个答案根本没有用。您基本上重申了问题所提到的内容:“由于 Mockito 不支持静态方法,我切换到 Power Mockito”,然后在提到 PowerMock 时,您给出了一个示例,该示例基本上重复了问题示例代码中的内容。 (2认同)