【发布时间】:2016-02-19 00:35:13
【问题描述】:
当某些东西被监视时,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;
}
}
我一无所知 - 有什么想法吗?
【问题讨论】:
-
你为什么不用浓缩咖啡:google.github.io/android-testing-support-library/docs/espresso 这样你也可以控制活动。
-
我已经在使用 Espresso,这与我的问题无关。
-
不可能向您的活动添加@VisibleForTesting setDelegate() 方法?我觉得任何涉及注入 Activity 间谍的方法总会有一些边缘情况,它不起作用。
-
没有真正阅读整个问题,但 Mockito 的 thenCallRealMethod() 不是你想要的吗?
-
@Jozua 是的,我相信这就是
Mockito.spy()已经在做的事情,因为它是Mockito.mock(myInstance.getClass(), withSettings().spiedInstance(myInstance).defaultAnswer(Mockito.CALL_REAL_METHODS));的简写