2016-01-20 18 views
0

我有一個Fragment實現,我想用Robolectric框架來測試。當我嘗試運行測試失敗,出現異常:當試圖實例化LayoutParams對象時,Robolectric中的NPE

java.lang.NullPointerException 
at org.robolectric.shadows.ShadowViewGroup$ShadowLayoutParams.__constructor__(ShadowViewGroup.java:141) 
at android.view.ViewGroup$LayoutParams.<init>(ViewGroup.java) 
at android.view.ViewGroup$MarginLayoutParams.<init>(ViewGroup.java)  
at android.widget.FrameLayout$LayoutParams.<init>(FrameLayout.java)  
at com.lalala.ui.FullPickerFragment.onCreateView(FullPickerFragment.java:41) 
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067) 
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248) 
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738) 
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613) 
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:517) 
at android.os.Handler.handleCallback(Handler.java:739) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at org.robolectric.shadows.ShadowMessageQueue.dispatchMessage(ShadowMessageQueue.java:130) 
at org.robolectric.shadows.ShadowMessageQueue.access$100(ShadowMessageQueue.java:29) 
at org.robolectric.shadows.ShadowMessageQueue$1.run(ShadowMessageQueue.java:95) 
at org.robolectric.util.Scheduler.runOrQueueRunnable(Scheduler.java:230) 
at org.robolectric.util.Scheduler.postAtFrontOfQueue(Scheduler.java:98) 
at org.robolectric.shadows.ShadowMessageQueue.enqueueMessage(ShadowMessageQueue.java:114) 
at android.os.MessageQueue.enqueueMessage(MessageQueue.java)  
at android.os.Handler.enqueueMessage(Handler.java:631) 
at android.os.Handler.sendMessageAtTime(Handler.java:600) 
at android.os.Handler.sendMessageDelayed(Handler.java:570) 
at android.os.Handler.post(Handler.java:326)  
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1519) 
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:634) 
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:613) 
at com.lalala.ui.FullPickerFragmentTest.init(FullPickerFragmentTest.java:137) 
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24) 
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:245) 
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:185) 
at org.robolectric.RobolectricTestRunner.runChild(RobolectricTestRunner.java:54) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)  
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)  
at org.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:149) 
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)  
at org.junit.runner.JUnitCore.run(JUnitCore.java:137) 
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69) 
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234) 
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74) 
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) 

它失敗在標有@Before標註在這條線的測試用例方法:

activity.getSupportFragmentManager() 
    .beginTransaction() 
    .add(pickerFragment, TAG) 
    .commit(); 

FullPicketFragment的代碼,它指的是發生在onCreateView方法,在這裏,它是:

public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     Log.d(LOG_TAG, "onCreateView()"); 
     fragmentView = inflater.inflate(R.layout.bf_full_picker, container, false); 
     mFragmentViewContainer = new FrameLayout(getActivity()); 
     ViewGroup.LayoutParams fragmentViewParams = fragmentView.getLayoutParams(); 
     FrameLayout.LayoutParams fragmentViewContainerParams = 
       new FrameLayout.LayoutParams(fragmentViewParams); 
     mFragmentViewContainer.setLayoutParams(fragmentViewContainerParams); 
     mFragmentViewContainer.addView(fragmentView); 
     return mFragmentViewContainer; 
    } 

正如你看到的,我只是誇大佈局,並將其放入FrameLayoutLayoutParams財產從充值的一個複製。 Robolectric無法創建該對象。

我該如何解決這個問題?

我試圖用另一個構造函數創建一個LayoutParams的副本,但它沒有幫助。此外,代碼本身工作正常的問題只在測試案例初始化。測試工作正常,直到我在onCreateView中做出這些更改。

我正在使用Robolectric 3.0-rc3。

回答

1

看來fragmentView.getLayoutParams()將它放入構造函數後返回null和line。你可以試試這個:

public View onCreateView(...) { 
    mFragmentViewContainer = new FrameLayout(inflater.getContext()); 
    fragmentView = inflater.inflate(
      R.layout.bf_full_picker, 
      mFragmentViewContainer, 
      **true**); 
    return mFragmentViewContainer; 
} 
+0

不知道它爲什麼有效,但它是。奇怪的是,應用程序運行正常,NPE只出現在測試中。 – Lingviston