2015-06-15 1 views
0

Я пытаюсь провести тестирование Fragment на Android с помощью Robolectric, и я знаю, что были некоторые другие сообщения о проблемах с FragmentActivity, когда он не был сохранен в какой-либо переменной.Ошибка «Действия были разрушены» при тестировании фрагментов с помощью Robolectric

Однако, я пытался сделать работу this post, и вы можете видеть в этом случае ссылку на объект FragmentActivity, поэтому проблема не должна быть проблемой. Вот базовый класс:

import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentActivity; 

import org.junit.After; 
import org.robolectric.Robolectric; 
import org.robolectric.util.ActivityController; 

public class FragmentTestCase<T extends Fragment> { 

private static final String FRAGMENT_TAG = "fragment"; 

private ActivityController controller; 
private FragmentActivity activity; 
private T fragment; 

public void startFragment(T fragment) { 
    this.fragment = fragment; 
    controller = Robolectric.buildActivity(FragmentActivity.class); 
    activity = (FragmentActivity) controller.create().start().visible().get(); 
    activity.getSupportFragmentManager() 
      .beginTransaction() 
      .add(fragment, FRAGMENT_TAG).commit(); 
} 

@After 
public void destroyFragment() { 
    if (fragment != null) { 
     activity.getSupportFragmentManager() 
       .beginTransaction() 
       .remove(fragment) 
       .commit(); 

     fragment = null; 
    } 
} 

public void pauseAndResumeFragment() { 
    controller.pause().resume(); 
} 

public T recreateFragment() { 
    activity.recreate(); 
    fragment = (T) activity.getSupportFragmentManager() 
      .findFragmentByTag(FRAGMENT_TAG); 

    return fragment; 
} 
} 

А вот реализация теста:

import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.robolectric.RobolectricGradleTestRunner; 
import org.robolectric.annotation.Config; 

import static org.assertj.core.api.Assertions.*; 

@RunWith(RobolectricGradleTestRunner.class) 
@Config(constants=BuildConfig.class, sdk=21) 
public class MainActivityFragmentTest extends FragmentTestCase<MainActivityFragment> { 

private MainActivityFragment fragment; 

@Before 
public void setUp() throws Exception { 
    fragment = new MainActivityFragment(); 
} 

@Test 
public void createsAndDestroysFragment() throws Exception { 
    startFragment(fragment); 
    assertThat(fragment).isNotNull(); 
} 

@Test 
public void pausesAndResumesFragment() throws Exception { 
    startFragment(fragment); 
    pauseAndResumeFragment(); 
    assertThat(fragment).isNotNull(); 
} 

@Test 
public void recreatesFragment() throws Exception { 
    startFragment(fragment); 
    fragment = recreateFragment(); 
    assertThat(fragment).isNotNull(); 
    } 
} 

После того, как я запускаю тест это ошибка, что я получаю:

java.lang.IllegalStateException: Activity has been destroyed 
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1399) 
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:637) 
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:616) 
at com.feyserflabs.musync.FragmentTestCase.destroyFragment(FragmentTestCase.java:36) 
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.RunAfters.evaluate(RunAfters.java:33) 
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.rt.execution.application.AppMain.main(AppMain.java:140) 

It кажется, что в какой-то момент активность уничтожается до ввода метода destroyFragment, но я не могу найти, где o почему. Любая помощь приветствуется.

ответ

1

Когда вы вызываете функцию activity.recreate(), вы фактически уничтожаете свою текущую деятельность, а ссылка, которую вы храните, становится недействительной. Затем вы пытаетесь использовать FragmentManager разрушенного действия, и он сработает.

+0

Спасибо! Это, похоже, решает эту ошибку. Несмотря на то, что я не понимаю, почему журнал ошибок указывает на строку 36 метода фиксации, а сразу после Activity.recreate() появляется вызов FragmentManager в том же самом действии, который не показывает никаких ошибок. –