我正在使用mockito-all
,version: '2.0.2-beta'
在Android仪器测试中模拟PowerManager
,这是最后一堂课,
我正在得到——
org.mockito.exceptions.base.MockitoException:
Cannot mock/spy class android.os.PowerManager
Mockito cannot mock/spy following:
- final classes
- anonymous classes
- primitive types
at com.crsardar.handson.android.mockito.ExampleInstrumentedTest.useAppContext(ExampleInstrumentedTest.java:38)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at android.support.test.runner.AndroidJUnit4.run(AndroidJUnit4.java:101)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:384)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1932)
我的应用程序build.gradle
如下 -
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.crsardar.handson.android.mockito"
minSdkVersion 25
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
configurations.all {
resolutionStrategy {
force 'com.android.support:support-annotations:26.1.0'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation group: 'org.mockito', name: 'mockito-all', version: '2.0.2-beta'
}
我的仪器测试用例如下 -
package com.crsardar.handson.android.mockito;
import android.content.Context;
import android.os.PowerManager;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
private Context mockedContext = null;
@Test
public void useAppContext() {
PowerManager mockedPowerManager = mock(PowerManager.class);
System.out.println("Before mockedPowerManager = " + mockedPowerManager.hashCode());
mockedContext = mock(Context.class);
when(mockedContext.getSystemService(Context.POWER_SERVICE)).thenReturn(mockedPowerManager);
System.out.println("After mockedPowerManager = " + mockedContext.getSystemService(Context.POWER_SERVICE).hashCode());
}
}
StackOverflow中现有的帖子都没有帮助,任何帮助都非常感谢
可以通过以下方式使用ShadowPowerManager:
private PowerManager powerManager;
private ShadowPowerManager shadowPowerManager;
@Before
public void before() {
powerManager = (PowerManager)ApplicationProvider.getApplicationContext().getSystemService(Context.POWER_SERVICE);
shadowPowerManager = shadowOf(powerManager);
shadowPowerManager.setIsScreenOn(false);
}
经过更多的研究,我发现 - 从这个版本的Mockito开始,这是不可能的。
好吧,我尝试使用本地jvm运行,
@RunWith(PowerMockRunner.class)
@PrepareForTest(PowerManager.class)
public class ExampleUnitTest2 {
@Mock
private Context mContext;
@Mock
private PowerManager mPowerManager;
@Before
public void setup(){
MockitoAnnotations.initMocks(this);
Mockito.when(mContext.getSystemService(Context.POWER_SERVICE)).thenReturn(mPowerManager);
System.out.println("After mockedPowerManager = " + mContext.getSystemService(Context.POWER_SERVICE).hashCode());
}
}
这是输出,
After mockedPowerManager = 793319856
After mockedPowerManager = 1340086275