我正在尝试测试
public class SomeClass {
public void execute(SomeContext context) {
final Activity someAndroidActivity = context.getActivityFromSomewhere();
final Timer t = new Timer();
t.schedule(new TimerTask() {
@Override
public void run() {
if (SomeOtherClass.someCondition()) {
someAndroidActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
someAndroidActivity.methodIWantToVerifyWasCalled();
}
});
t.cancel();
}
}
}, 0, 5000);
}
}
我必须使用PowerMock来模拟静态方法SomeOtherClass.someCondition()
测试如下:
@RunWith(PowerMockRunner.class)
@PrepareForTest(SomeOtherClass.class)
public class SomeClassTest {
@Test
public void testExecution() {
SomeContext someContext = Mockito.mock(SomeContext.class);
Activity activity = Mockito.mock(Activity.class);
PowerMockito.mockStatic(SomeOtherClass.class);
PowerMockito.when(SomeOtherClass.someCondition()).thenReturn(true);
// Run the Runnable passed to runOnUiThread
Mockito.doAnswer(new Answer<Void>() {
@Override
public Void answer(final InvocationOnMock invocation) throws Throwable {
((Runnable) invocation.getArguments()[0]).run();
return null;
}
}).when(activity).runOnUiThread(Mockito.isA(Runnable.class));
Mockito.when(someContext.getActivityFromSomewhere()).thenReturn(activity);
SomeClass someClass = new SomeClass();
// execute
someClass.execute(someContext);
// verify
Mockito.verify(activity).methodIWantToVerifyWasCalled();
}
}
运行此程序时,我收到线路...}).when(activity).runOnUiThread(Mockito.isA(Runnable.class));
的RuntimeException: Stub!
错误
当使用@RunWith(RobolectricTestRunner.class)
而不是PowerMock运行时,使用相同的doAnswer
方法不会出现此错误。
你知道我的问题是什么吗?有更好的方法吗?
通过删除PowerMock并覆盖RobolectricTestRunner:的行为来解决问题
public class TestRunner extends RobolectricTestRunner {
public TestRunner(final Class<?> testClass) throws InitializationError {
super(testClass);
}
@Override
protected ClassLoader createRobolectricClassLoader(final Setup setup, final SdkConfig sdkConfig) {
return super.createRobolectricClassLoader(new newShadowsSetup(), sdkConfig);
}
class newShadowsSetup extends Setup {
@Override
public boolean shouldInstrument(final ClassInfo info) {
if (info.getName().contains("SomeOtherClass")) {
return true;
}
if (super.shouldInstrument(info)) {
return true;
}
return false;
}
}
}
更换
@RunWith(PowerMockRunner.class)
@PrepareForTest(SomeOtherClass.class)
带有
@RunWith(TestRunner.class)
@Config(shadows = {
SomeOtherClassShadow.class
})
创建阴影SomeOtherClassShadow
@Implements(SomeOtherClass.class)
public class SomeOtherClassShadow {
@Implementation
static public boolean someCondition() {
return true;
}
}