如何正确监视活动

时间:2016-02-19 00:35:13

标签: android mockito

Mockito在监视一些事情时会创建一个代理实例。现在,有没有办法将在该代理实例上执行的setter转发到它后面的真实实例?

理由:我有一个我完全没有控制的对象实例,即Android活动。我可以为我的应用程序的大多数部分提供代理版本并且运行正常,因为我需要在活动的创建阶段很早就创建间谍/代理,它还没有完全实例化,例如基础上下文未附加。这发生在代理实例上,当然不被活动实例本身使用(它通过Activity.this引用自身)。最终的结果是,这会导致各种崩溃,因为资源解析是通过这个基础上下文发生的,所以内部的Fragment机制会抛出NPE等等。

以下是一些代码:

public class CustomAndroidJUnitRunner extends AndroidJUnitRunner {
    @Override
    public Activity newActivity(ClassLoader cl, String className, Intent intent)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        Activity activity = super.newActivity(cl, className, intent);
        return maybeStubSomeDelegate(activity);
    }

    private Activity maybeStubSomeDelegate(Activity activity) {
        if (!(activity instanceof SomeDelegate)) {
            return activity;
        }
        Activity spiedActivity = spy(activity);
        doReturn(SomeDelegateMock.getInstance())
            .when((SomeDelegate) spiedActivity)
            .getDelegate();
        return spiedActivity;
    }
}

我很无能为力 - 任何想法?

2 个答案:

答案 0 :(得分:1)

您可以使用Robolectric创建自己的代理(或Robolectric称之为" Shadows")到您的活动中,

创建代理时,您可以创建自己的可以触发真实对象方法的setter,

如何创建阴影示例:

@Implements(Bitmap.class)
public class MyShadowBitmap {

@RealObject private Bitmap realBitmap;
private int bitmapQuality = -1;

@Implementation
public boolean compress(Bitmap.CompressFormat format, int quality, OutputStream stream) {
  bitmapQuality = quality;
  return realBitmap.compress(format, quality, stream);
}

public int getQuality() {
  return bitmapQuality;
}
}
}

当@RealObject是你的真实实例时,

要使用Robolectric测试运行器使用此阴影,请按如下方式定义新的测试类:

@RunWith(RobolectricTestRunner.class)
@Config(shadows = MyShadowBitmap.class)
public class MyTestClass {}

要拉出当前阴影实例,请使用以下方法:

shadowOf()

无论如何,这里是Robolectric的链接:

http://robolectric.org/custom-shadows/

答案 1 :(得分:1)

使用:

android测试支持库的   SingleActivityFactory,   ActivityTestRule 和Mockito的   spy()

dependencies {
  androidTestImplementation 'com.android.support.test:runner:1.0.2'
  androidTestImplementation 'com.android.support.test:rules:1.0.2'
  androidTestImplementation 'org.mockito:mockito-android:2.21.0'
}

概述:

将间谍实例注入SingleActivityFactory的实现中

代码:

public class MainActivityTest {
    MainActivity subject;

    SingleActivityFactory<MainActivity> activityFactory = new SingleActivityFactory<MainActivity>(MainActivity.class) {
        @Override
        protected MainActivity create(Intent intent) {
            subject = spy(getActivityClassToIntercept());
            return subject;
        }
    };

    @Rule
    public ActivityTestRule<MainActivity> testRule = new ActivityTestRule<>(activityFactory, true, true);

    @Test
    public void activity_isBeingSpied() {
        verify(subject).setContentView(R.layout.activity_main);
    }

}