但是,如果测试中的活动是ActionBarActivity,则会出现以下异常:
java.lang.IllegalArgumentException: android.content.pm.PackageManager$NameNotFoundException: ComponentInfo{mypackage.view.activity/mypackage.view.activity.MyActivity} at android.support.v4.app.NavUtils.getParentActivityName(NavUtils.java:282) at android.support.v7.app.ActionBarActivityDelegate.onCreate(ActionBarActivityDelegate.java:116) at android.support.v7.app.ActionBarActivityDelegateICS.onCreate(ActionBarActivityDelegateICS.java:57) at android.support.v7.app.ActionBarActivity.onCreate(ActionBarActivity.java:98) at mypackage.view.activity.MyActivity.onCreate(MyActivity.java:68) at android.app.Activity.performCreate(Activity.java:5231) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) at android.test.ActivityUnitTestCase.startActivity(ActivityUnitTestCase.java:158) at mypackage.MyActivityTest.test(MyActivityTest.java:89) at java.lang.reflect.Method.invokeNative(Native Method) at android.test.InstrumentationTestCase.runMethod(InstrumentationTestCase.java:214) at android.test.InstrumentationTestCase.runTest(InstrumentationTestCase.java:199) at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191) at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176) at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:554) at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1701) Caused by: android.content.pm.PackageManager$NameNotFoundException: ComponentInfo{mypackage.view.activity/mypackage.view.activity.MyActivity} at android.app.ApplicationPackageManager.getActivityInfo(ApplicationPackageManager.java:242) at android.support.v4.app.NavUtils.getParentActivityName(NavUtils.java:298) at android.support.v4.app.NavUtils.getParentActivityName(NavUtils.java:279) ... 21 more
我的测试类如下所示:
public class MyActivityTest extends ActivityUnitTestCase<MyActivity> { ... public MyActivityTest() { super(MyActivity.class); } private Context context; private TestBaseApplication application; @Override protected void setUp() throws Exception { super.setUp(); context = new ContextThemeWrapper( getInstrumentation().getTargetContext(),R.style.Theme_AppCompat){ @Override public Context getApplicationContext() { return application; } }; application = new TestBaseApplication( context); setApplication(application); ... } public void test() throws InterruptedException { setActivityContext( context); Intent intent = new Intent( context,MyActivity.class); startActivity(intent,null,null); ... } }
该活动出现在AndroidManifest中,如下所示:
<activity android:name=".view.activity.MyActivity" android:icon="@drawable/actionbar_logo" android:screenOrientation="portrait" android:parentActivityName="mypackage.ParentActivity"> <Meta-data android:name="android.support.PARENT_ACTIVITY" android:value="mypackage.ParentActivity"/> </activity>
经过一些故障排除后,我尝试在上面的链接上运行示例,它工作正常,即使我更改活动以扩展ActionBarActivity.
由于我无法找到问题的原因,我也玩了清单,build.gradle等.现在,我只是坚持这个,我想不出别的什么.
This post也可能与问题有关,但也没有任何评论.并且this post似乎也有类似的问题,但那里的解决方案不起作用,因为我不希望真正的应用程序与活动一起启动.
编辑:
我创建了一个简单的单独项目,以便隔离问题.
首先,我为一个扩展ActionBarActivity的Activity编写了一个ActivityUnitTestCase.它工作正常.
在那之后,我尝试添加更多的活动,使它们成为彼此的父级.(因此它看起来像我的实际项目).这也很好.
最后,我添加了更多ActivityUnitTestCase类,其中包含与我的实际项目不同的活动,所有活动都扩展了ActionBarActivity,并为所有活动设置了相同的设置,并在两个设备上运行测试,一个是模拟器(Genymotion),另一个是我的物理设备. (Nexus 4)
测试都在模拟器上给出了NameNotFoundException.除了其中一项测试外,所有测试都在物理设备上传递,这让我更加困惑.
解决方法
使用ActivityUnitTestCase.startAcitvity()构建的活动具有指向应用程序包的componentName.因此,当ActionBarActivity检查父活动以更新Up符号时,如果活动不在应用程序“root”包中,则测试会崩溃.
幸运的是,问题描述中提出的解决方法工作正常,因此在修复之前,只需制作ActivityUnitTestCase的本地副本,更新下面定义componentName的行,并确保您的测试用例扩展该类而不是原始的ActivityUnitTestCase.
// replace this line new ComponentName(mActivityClass.getPackage().getName(),mActivityClass.getName()); // with this new ComponentName(getInstrumentation().getTargetContext(),mActivityClass);