由于方法getApplicationContext
位于您正在扩展的类中,因此会出现一些问题。有几个问题需要考虑:
在这种情况下,您可以选择对象组合而非继承。因此,为了使您的Activity
可测试,您需要稍微分解逻辑。假设您的Activity
名为MyActivity
。它需要由一个逻辑组件(或类)组成,让我们将其命名为MyActivityLogic
。以下是一个简单的类图示例:
为了解决单例问题,我们将逻辑与应用程序上下文“注入”,以便可以使用模拟进行测试。然后,我们只需要测试
MyActivity
对象是否已将正确的应用程序上下文放入
MyActivityLogic
中即可。我们基本上是通过
另一层抽象(引用自Butler Lampson)来解决这两个问题。在此情况下,我们添加的新层是将活动逻辑移出活动对象。
为了您的示例,类需要看起来像这样:
public final class MyActivityLogic {
private MyApp mMyApp;
public MyActivityLogic(MyApp pMyApp) {
mMyApp = pMyApp;
}
public MyApp getMyApp() {
return mMyApp;
}
public void onClick(View pView) {
getMyApp().setNewState();
}
}
public final class MyActivity extends Activity {
private final MyActivityLogic mLogic;
public MyActivity() {
super();
mLogic = new MyActivityLogic(
(MyApp) getApplicationContext());
}
public MyActivityLogic getMyActivityLogic() {
return mLogic;
}
public void onClick(View pView) {
mLogic.onClick(pView);
}
}
所有内容应该看起来像这样:
要测试MyActivityLogic
,你只需要一个简单的jUnitTestCase
,而不是ActivityUnitTestCase
(因为它不是一个活动),并且您可以使用您选择的mocking框架模拟您的应用程序上下文(因为手动编写自己的mocks有点烦人)。示例使用Mockito:
MyActivityLogic mLogic;
MyApplication mMyApplication;
protected void setUp() {
mMyApplication = mock(MyApplication.class);
mLogic = new MyActivityLogic(mMyApplication);
}
public void testOnClickShouldSetNewStateOnAppContext() {
mLogic.onClick(null);
verify(mMyApplication).setNewState();
}
要测试 MyActivity
,您可以像往常一样使用 ActivityUnitTestCase
,我们只需要确保它创建了一个正确的 ApplicationContext
的 MyActivityLogic
。以下是一个草率的测试代码示例,它可以完成所有这些:
MyActivity vMyActivity = getActivity();
MyApp expectedAppContext = vMyActivity.getApplicationContext();
MyActivityLogic vLogic = vMyActivity.getMyActivityLogic();
MyApp actualAppContext = vLogic.getMyApp();
assertSame(expectedAppContext, actualAppContext);
希望这些对你有所帮助并且易于理解。