【问题标题】:NameNotFoundException at ActivityUnitTestCase with ActionBarActivityActivityUnitTestCase 的 NameNotFoundException 与 ActionBarActivity
【发布时间】:2014-09-05 18:36:53
【问题描述】:

我正在尝试为现有应用程序编写一些测试。我想为测试提供一个测试应用程序类,我遵循示例here,因为我也在使用 Dagger 进行 DI。

但是,如果被测活动是 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);
        ...
    }
}

Activity在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。

由于我无法找到问题的原因,我还使用了 manifest、build.gradle 等。现在,我只是被这个卡住了,我想不出其他任何东西了。

This post也可能与该问题密切相关,但对此也没有任何评论。 this post 似乎也有类似的问题,但那里的解决方案对我不起作用,因为我不希望真正的应用程序与活动一起启动。

编辑

我创建了一个简单的单独项目,以隔离问题。

首先,我为扩展 ActionBarActivity 的 Activity 编写了一个 ActivityUnitTestCase。效果很好。

在那之后,我尝试添加更多活动,使它们成为彼此的父项。(这样看起来就像我的实际项目)。而且效果也很好。

最后,我添加了更多 ActivityUnitTestCase 类,这些类与我的实际项目中的活动不同,都扩展了 ActionBarActivity,所有这些活动都具有相同的设置,并在两台设备上运行测试,一个是模拟器 (Genymotion),另一个是是我的物理设备。 (连结 4)

测试都在模拟器上给出了 NameNotFoundException。除了一项测试之外,所有测试都在物理设备上通过,这让我更加困惑。

【问题讨论】:

  • 如果我不得不猜测,这是 AppCompat 查找父活动的方式中的一个错误,只有在使用来自仪器测试的 Context 时才能看到。但这只是一个猜测。您可以尝试创建一个小的单独项目(和测试),看看您是否可以单独复制它。如果可以,并且您确定您使用的是最新版本的 appcompat-v7,请在 the issue tracker 上使用示例项目和堆栈跟踪提交问题。
  • @CommonsWare:感谢您的评论。用您的建议结果更新了我的帖子。可能存在您建议的错误,但绝对无法在单独的项目中重现它,以便我可以提出问题。
  • 不幸的是,这也限制了任何人提供帮助的能力,因为我们也不太可能重现它。 :-(

标签: android unit-testing android-testing android-actionbaractivity


【解决方案1】:

这一切都归结为ActivityUnitTestCase 中的bug

使用ActivityUnitTestCase.startAcitvity() 构建的活动有一个componentName 指向应用程序包。因此,当ActionBarActivity 检查父 Activity 以更新 Up 符号时,如果该 Activity 不在应用程序的“根”包中,则测试会崩溃。

幸运的是,问题描述中提出的解决方法可以正常工作,因此在解决此问题之前,只需制作 ActivityUnitTestCase 的本地副本,更新定义 componentName 的行,如下所示,并确保您的测试用例扩展了该类,而不是原来的 ActivityUnitTestCase

// replace this line
new ComponentName(mActivityClass.getPackage().getName(), mActivityClass.getName());

// with this
new ComponentName(getInstrumentation().getTargetContext(), mActivityClass);

【讨论】:

  • 谢谢你,它确实帮助了我。 :) 我刚刚复制了 ActivityUnitTestCase 并将行更改为“ComponentName cn = new ComponentName(getInstrumentation().getTargetContext(), mActivityClass);”
  • 或者您可以将活动移动到根包,但该解决方案可能不太理想
猜你喜欢
  • 2014-04-17
  • 1970-01-01
  • 1970-01-01
  • 2016-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-25
  • 1970-01-01
相关资源
最近更新 更多