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

Mocking method calls using power mockito - org.powermock.api.mockito.ClassNotPreparedException(使用 power mockito 模拟方法调用 - org.powermock.api.mockito.ClassNotPreparedException)
本文介绍了使用 power mockito 模拟方法调用 - org.powermock.api.mockito.ClassNotPreparedException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

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

 Base64.encodeToString(byteArray, Base64.DEFAULT);

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

 PowerMockito.mockStatic(Base64.class);

但 Android Studio 正在返回我仍然返回如下错误.

<块引用>

org.powermock.api.mockito.ClassNotPreparedException:类android.util.Base64 未准备好进行测试.要准备这堂课,请添加'@PrepareForTest' 注释的类.

下面是我的完整代码.

要测试的代码:

导入android.graphics.Bitmap;导入android.graphics.BitmapFactory;导入 android.util.Base64;导入android.widget.ImageView;公共静态字符串 convertBitmapToBase64(位图 imageBitmap, boolean withCompression) {ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();imageBitmap.compress(Bitmap.CompressFormat.PNG, 120, byteArrayOutputStream);byte[] byteArray = byteArrayOutputStream.toByteArray();返回 Base64.encodeToString(byteArray, Base64.DEFAULT);}

测试类代码

导入android.graphics.Bitmap;导入 android.util.Base64;导入 org.junit.Before;导入 org.junit.runner.RunWith;导入 org.mockito.MockitoAnnotations;导入 org.powermock.api.mockito.PowerMockito;导入 org.powermock.core.classloader.annotations.PrepareForTest;导入 org.powermock.modules.junit4.PowerMockRunner;导入 org.testng.annotations.Test;@RunWith(PowerMockRunner.class)@PrepareForTest({Base64.class})公共类 ImageLoaderTest {@测试公共无效 testConvertBitmap(){字节[]数组=新字节[20];PowerMockito.mockStatic(Base64.class);PowerMockito.when(Base64.encodeToString(array, Base64.DEFAULT)).thenReturn("asdfghjkl");位图 mockedBitmap=PowerMockito.mock(Bitmap.class);字符串输出 = ImageLoaderUtils.convertBitmapToBase64(mockedBitmap);断言 (!output.isEmpty());}

}

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'

解决方案

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

<块引用>

Mockito 有什么限制

  • 无法模拟最终课程
  • 无法模拟静态方法
  • 不能模拟最终方法 - 它们的真实行为会毫无例外地执行.Mockito 无法警告您模拟最终方法,所以保持警惕.

有关此限制的更多信息:

<块引用>

我可以模拟静态方法吗?

<块引用>

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

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

@RunWith(PowerMockRunner.class)@PrepareForTest( { Base64.class })公共类 YourTestCase {@测试公共无效测试静态(){模拟静态(Base64.class);when(Base64.encodeToString(argument)).thenReturn("预期结果");}}

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

mock-maker-inline

编辑 2:由于 Mockito 3.4.0 现在可以 模拟静态方法:

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

此外,您可以直接添加为依赖项 org.mockito:mockito-inline:+ 并避免手动创建 or.mockito.plugins.MockMaker 文件

从 Mockito 3.5.0 开始,您还可以 模拟对象构造.

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'

解决方案

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.

这篇关于使用 power mockito 模拟方法调用 - org.powermock.api.mockito.ClassNotPreparedException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

How can I use CClistview in COCOS2d Android?(如何在 COCOS2d Android 中使用 CClistview?)
cocos2d-android: how to display score(cocos2d-android:如何显示分数)
Sqlite database not copied from asset folder Android(Sqlite 数据库未从资产文件夹 Android 复制)
SQLite Database Copy Appears Corrupted When Generated by Device and not Emulator(SQLite 数据库副本在由设备而不是模拟器生成时出现损坏)
Android file copy(安卓文件拷贝)
Android how to detect Copy event of Edittext in android(Android如何在android中检测Edittext的Copy事件)