我有一个图像加载器类,我需要在其中测试一些静态方法.由于 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 更喜欢面向对象和依赖注入难以理解的静态程序代码改变.如果你处理可怕的遗留代码,你可以使用 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!
EditText:禁用文本选择处理程序单击事件上的粘贴EditText: Disable Paste/Replace menu pop-up on Text Selection Handler click event(EditText:禁用文本选择处理程序单击事件上的粘贴/替换菜
2.3 上带有完成 SoftInput 操作标签的多行 EditTextMultiline EditText with Done SoftInput Action Label on 2.3(2.3 上带有完成 SoftInput 操作标签的多行 EditText)
如何在 Android 中检测向左或向右滑动?How to detect the swipe left or Right in Android?(如何在 Android 中检测向左或向右滑动?)
防止在Android中的屏幕旋转对话框解除Prevent dialog dismissal on screen rotation in Android(防止在Android中的屏幕旋转对话框解除)
如何处理 ImeOptions 的完成按钮点击?How do I handle ImeOptions#39; done button click?(如何处理 ImeOptions 的完成按钮点击?)
您如何将 EditText 设置为仅接受 Android 中的数值How do you set EditText to only accept numeric values in Android?(您如何将 EditText 设置为仅接受 Android 中的数值?)