7

我想爲現有的應用程序編寫一些測試。我想爲測試提供一個測試應用程序類,我遵循示例here,因爲我也使用Dagger作爲DI。NameNotFoundException在ActivityUnitTestCase與ActionBarActivity

然而,如果被測活動是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> 

經過一些故障排除後,我試着運行ex充足的鏈接上面,它工作得很好,即使當我改變活動來擴展ActionBarActivity。

由於我無法找到問題的原因,我也玩弄了manifest,build.gradle等。現在,我只是堅持這一點,我想不出其他任何東西。

This post也可能接近相關的問題,但也沒有任何評論。而且this post也似乎有類似的問題,但是那裏的解決方案並不能解決我的問題,因爲我不希望真正的應用程序與該活動一起啓動。

編輯

我創建了一個簡單的單獨的項目,以找出問題。

首先,我爲Activity擴展了ActionBarActivity編寫了一個ActivityUnitTestCase。它運行良好。

之後,我嘗試添加更多的活動,使他們彼此的父母(使它看起來像我的實際項目)。這也工作得很好。

最後,我從我的實際項目中添加了更多ActivityUnitTestCase類,它們具有不同的活動,所有擴展的ActionBarActivity都具有相同的設置,並在兩個設備上運行測試,一個是模擬器(Genymotion)其他是我的物理設備。 (Nexus 4)

測試都在模擬器上給了NameNotFoundException。除了其中一項測試外,其他測試都通過了物理設備,這讓我更加困惑。

+1

如果我不得不猜測,這是AppCompat查找父活動的一種錯誤,僅在使用儀器測試中的'Context'時纔會出現。但這只是一個猜測。您可以嘗試創建一個小型單獨項目(和測試),以查看是否可以單獨重現它。如果可以,並且您確定自己使用的是最新版本的「appcompat-v7」,請使用示例項目和堆棧跟蹤在[問題跟蹤器](http://b.android.com)上提出問題。 – CommonsWare

+0

@CommonsWare:感謝您的評論。用您的建議結果更新我的帖子。可能存在像您建議的錯誤,但絕對無法在單獨的項目中重現它,以至於我可以提出問題。 –

+0

不幸的是,這也限制了任何人的幫助能力,因爲我們也不可能重現它。 :-( – CommonsWare

回答

10

這一切歸結於這bugActivityUnitTestCase

使用ActivityUnitTestCase.startAcitvity()構建的活動具有指向應用程序包的componentName。因此,當ActionBarActivity檢查父活動以更新Up符號時,如果活動不在應用程序的「根」包中,則測試會崩潰。

幸好在發行說明書中提出的解決方法工作得很好,所以直到這個是固定的,只是做的ActivityUnitTestCase本地副本,更新其中組件名定義如下行,並確保你的測試用例擴展該類而不是原來的ActivityUnitTestCase

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

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

謝謝你,這真的幫了我:)我剛剛複製ActivityUnitTestCase並將行更改爲「ComponentName cn = new ComponentName(getInstrumentation()。getTargetContext(),mActivityClass);」 – scrrr

+0

或者您可以將活動移動到根包,但該解決方案可能不太理想 –

相關問題