Robolectric 尝试实例化 LayoutParams 对象时出现 NPE
NPE in Robolectric when trying to instantiate LayoutParams object
我有一个 Fragment
实现,我想使用 Robolectric
框架对其进行测试。当我尝试 运行 测试时,它失败并出现异常:
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.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.access0(ShadowMessageQueue.java:29)
at org.robolectric.shadows.ShadowMessageQueue.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.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.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.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=11=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.robolectric.RobolectricTestRunner.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;
}
如您所见,我只是膨胀布局并将其放入 FrameLayout
中,并从膨胀的布局中复制 LayoutParams
属性。 Robolectric 无法创建 LayoutParams
对象。
我该如何解决这个问题?
我尝试使用另一个构造函数创建 LayoutParams
的副本,但没有帮助。此外,代码本身工作正常,问题仅出现在测试用例初始化中。在我在 onCreateView
.
中进行这些更改之前,测试工作正常
我正在使用 Robolectric 3.0-rc3.
似乎fragmentView.getLayoutParams()
returns null and line 在它被放入构造函数之后。你可以试试这个:
public View onCreateView(...) {
mFragmentViewContainer = new FrameLayout(inflater.getContext());
fragmentView = inflater.inflate(
R.layout.bf_full_picker,
mFragmentViewContainer,
**true**);
return mFragmentViewContainer;
}
我有一个 Fragment
实现,我想使用 Robolectric
框架对其进行测试。当我尝试 运行 测试时,它失败并出现异常:
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.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.access0(ShadowMessageQueue.java:29)
at org.robolectric.shadows.ShadowMessageQueue.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.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.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.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=11=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.robolectric.RobolectricTestRunner.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;
}
如您所见,我只是膨胀布局并将其放入 FrameLayout
中,并从膨胀的布局中复制 LayoutParams
属性。 Robolectric 无法创建 LayoutParams
对象。
我该如何解决这个问题?
我尝试使用另一个构造函数创建 LayoutParams
的副本,但没有帮助。此外,代码本身工作正常,问题仅出现在测试用例初始化中。在我在 onCreateView
.
我正在使用 Robolectric 3.0-rc3.
似乎fragmentView.getLayoutParams()
returns null and line 在它被放入构造函数之后。你可以试试这个:
public View onCreateView(...) {
mFragmentViewContainer = new FrameLayout(inflater.getContext());
fragmentView = inflater.inflate(
R.layout.bf_full_picker,
mFragmentViewContainer,
**true**);
return mFragmentViewContainer;
}