問題描述
我有一個圖像加載器類,我需要在其中測試一些靜態(tài)方法.由于 Mockito 不支持靜態(tài)方法,我切換到 Power Mockito.但是我正在測試的靜態(tài)方法有一個方法調(diào)用
Base64.encodeToString(byteArray, Base64.DEFAULT);
為了模擬這個,我使用 mockStatic 方法如下,帶有@PrepareForTest 注釋.
PowerMockito.mockStatic(Base64.class);
但 Android Studio 正在返回我仍然返回如下錯誤.
<塊引用>org.powermock.api.mockito.ClassNotPreparedException:類android.util.Base64 未準(zhǔn)備好進行測試.要準(zhǔn)備這堂課,請?zhí)砑?@PrepareForTest' 注釋的類.
下面是我的完整代碼.
要測試的代碼:
導(dǎo)入android.graphics.Bitmap;導(dǎo)入android.graphics.BitmapFactory;導(dǎo)入 android.util.Base64;導(dǎo)入android.widget.ImageView;公共靜態(tài)字符串 convertBitmapToBase64(位圖 imageBitmap, boolean withCompression) {ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();imageBitmap.compress(Bitmap.CompressFormat.PNG, 120, byteArrayOutputStream);byte[] byteArray = byteArrayOutputStream.toByteArray();返回 Base64.encodeToString(byteArray, Base64.DEFAULT);}
測試類代碼
導(dǎo)入android.graphics.Bitmap;導(dǎo)入 android.util.Base64;導(dǎo)入 org.junit.Before;導(dǎo)入 org.junit.runner.RunWith;導(dǎo)入 org.mockito.MockitoAnnotations;導(dǎo)入 org.powermock.api.mockito.PowerMockito;導(dǎo)入 org.powermock.core.classloader.annotations.PrepareForTest;導(dǎo)入 org.powermock.modules.junit4.PowerMockRunner;導(dǎo)入 org.testng.annotations.Test;@RunWith(PowerMockRunner.class)@PrepareForTest({Base64.class})公共類 ImageLoaderTest {@測試公共無效 testConvertBitmap(){字節(jié)[]數(shù)組=新字節(jié)[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 有什么限制
- 無法模擬最終課程
- 無法模擬靜態(tài)方法
- 不能模擬最終方法 - 它們的真實行為會毫無例外地執(zhí)行.Mockito 無法警告您模擬最終方法,所以保持警惕.
有關(guān)此限制的更多信息:
<塊引用>我可以模擬靜態(tài)方法嗎?
<塊引用>沒有.Mockito 更喜歡面向?qū)ο蠛鸵蕾囎⑷腚y以理解的靜態(tài)程序代碼改變.如果你處理可怕的遺留代碼,你可以使用 JMockit 或 Powermock 來模擬靜態(tài)方法.
如果你想使用 PowerMock 試試這樣:
@RunWith(PowerMockRunner.class)@PrepareForTest( { Base64.class })公共類 YourTestCase {@測試公共無效測試靜態(tài)(){模擬靜態(tài)(Base64.class);when(Base64.encodeToString(argument)).thenReturn("預(yù)期結(jié)果");}}
在 Mockito 2 現(xiàn)在可以模擬最終類和最終方法.這是一個可選的選項.您需要使用以下內(nèi)容創(chuàng)建文件 src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
:
mock-maker-inline
編輯 2:由于 Mockito 3.4.0 現(xiàn)在可以 模擬靜態(tài)方法:
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:+
并避免手動創(chuàng)建 or.mockito.plugins.MockMaker 文件
從 Mockito 3.5.0 開始,您還可以 模擬對象構(gòu)造.
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.
這篇關(guān)于使用 power mockito 模擬方法調(diào)用 - org.powermock.api.mockito.ClassNotPreparedException的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!