在Fragment Arch组件上运行简单的Robolectric测试ViewModel会导致在运行应用程序时不会发生崩溃。
@Test
public void shouldNotBeNull() throws Exception {
SelectFunctionFragment fragment = new SelectFunctionFragment();
SupportFragmentTestUtil.startVisibleFragment(fragment);
assertNotNull(fragment.getView());
}
Crash Stacktrace:
java.lang.IllegalStateException:FragmentManager已在执行事务
at android.support.v4.app.FragmentManagerImpl.ensureExecReady(FragmentManager.java:2177)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2233)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:700)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at org.robolectric.shadows.ShadowMessageQueue.dispatchMessage(ShadowMessageQueue.java:164)
at org.robolectric.shadows.ShadowMessageQueue.access$100(ShadowMessageQueue.java:30)
at org.robolectric.shadows.ShadowMessageQueue$1.run(ShadowMessageQueue.java:138)
at org.robolectric.util.Scheduler.runOrQueueRunnable(Scheduler.java:319)
at org.robolectric.util.Scheduler.postDelayed(Scheduler.java:156)
at org.robolectric.util.Scheduler.postDelayed(Scheduler.java:145)
at org.robolectric.shadows.ShadowMessageQueue.enqueueMessage(ShadowMessageQueue.java:145)
at android.os.MessageQueue.enqueueMessage(MessageQueue.java)
at android.os.Handler.enqueueMessage(Handler.java:662)
at android.os.Handler.sendMessageAtTime(Handler.java:631)
at android.os.Handler.sendMessageDelayed(Handler.java:601)
at android.os.Handler.post(Handler.java:357)
at android.support.v4.app.FragmentManagerImpl.scheduleCommit(FragmentManager.java:2108)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:2091)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:678)
at android.support.v4.app.BackStackRecord.commitAllowingStateLoss(BackStackRecord.java:637)
at android.arch.lifecycle.HolderFragment$HolderFragmentManager.createHolderFragment(HolderFragment.java:152)
at android.arch.lifecycle.HolderFragment$HolderFragmentManager.holderFragmentFor(HolderFragment.java:171)
at android.arch.lifecycle.HolderFragment.holderFragmentFor(HolderFragment.java:84)
at android.arch.lifecycle.ViewModelStores.of(ViewModelStores.java:47)
at android.arch.lifecycle.ViewModelProviders.of(ViewModelProviders.java:89)
at <redacted>.SelectFunctionFragment.onViewCreated(SelectFunctionFragment.java:38)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1430)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1750)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1819)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:797)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2590)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2377)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2332)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2239)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:700)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at org.robolectric.shadows.ShadowMessageQueue.dispatchMessage(ShadowMessageQueue.java:164)
at org.robolectric.shadows.ShadowMessageQueue.access$100(ShadowMessageQueue.java:30)
at org.robolectric.shadows.ShadowMessageQueue$1.run(ShadowMessageQueue.java:138)
at org.robolectric.util.Scheduler.runOrQueueRunnable(Scheduler.java:319)
at org.robolectric.util.Scheduler.postDelayed(Scheduler.java:156)
at org.robolectric.util.Scheduler.postDelayed(Scheduler.java:145)
at org.robolectric.shadows.ShadowMessageQueue.enqueueMessage(ShadowMessageQueue.java:145)
at android.os.MessageQueue.enqueueMessage(MessageQueue.java)
at android.os.Handler.enqueueMessage(Handler.java:662)
at android.os.Handler.sendMessageAtTime(Handler.java:631)
at android.os.Handler.sendMessageDelayed(Handler.java:601)
at android.os.Handler.post(Handler.java:357)
at android.support.v4.app.FragmentManagerImpl.scheduleCommit(FragmentManager.java:2108)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:2091)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:678)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:632)
at org.robolectric.shadows.support.v4.SupportFragmentTestUtil.startVisibleFragment(SupportFragmentTestUtil.java:27)
at <redacted>.SelectFunctionFragmentTest.shouldNotBeNull(SelectFunctionFragmentTest.java:32)
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.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:568)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.robolectric.internal.SandboxTestRunner$2.evaluate(SandboxTestRunner.java:253)
at org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:130)
at org.robolectric.internal.SandboxTestRunner.runChild(SandboxTestRunner.java:42)
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.internal.SandboxTestRunner$1.evaluate(SandboxTestRunner.java:84)
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:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
at com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:131)
崩溃起源于这一行:
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
viewModel = ViewModelProviders.of(getActivity()).get(WizardViewModel.class);
相关组件版本:
implementation "android.arch.lifecycle:extensions:1.1.0"
testImplementation 'junit:junit:4.12'
testImplementation "org.robolectric:robolectric:3.7.1"
testCompile 'org.robolectric:shadows-support-v4:3.3.2'
如果我使用具有ViewModel初始化延迟的代码运行相同的测试,它可以正常运行并且不会崩溃。
有什么方法可以避免这种情况吗?