6

ここから、githubとrobolectricのブログからたくさんのリンクを読んでいますが、まだ実用的な解決策は見つかりませんでした(すでにRobolectric 2.0 alpha 2を使用しています)。Robolectric:SherlockFragmentを含むアクティビティをテストするにはどうすればよいですか?

UPDATE:私たちはandroid.support.v4.app.FragmentためSherlockFragmentを交換しても問題も起こります。

私はこのtipに従った後SherlockFragmentActivityをテストすることができましたが、私はこのフラグメントを追加するとき、それはSherlockFragmentで、私の活動のXMLへ:

<fragment 
    android:name="com.marcelopazzo.fragmentapplication.ExampleFragment" 
    android:id="@+id/example_fragment" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" /> 

SherlockFragmentクラス:

public class ExampleFragment extends SherlockFragment { 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     return inflater.inflate(R.layout.example_fragment, container, false); 
    } 
} 

これは断片によって膨らんでいるレイアウトです:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 

    <TextView 
     android:id="@+id/hello_again" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="@string/hello_again" /> 

</LinearLayout> 

私は次のエラーを取得する:

java.lang.NullPointerException 
    at org.robolectric.shadows.ShadowViewGroup.addView(ShadowViewGroup.java:69) 
    at android.view.ViewGroup.addView(ViewGroup.java) 
    at org.robolectric.res.builder.LayoutBuilder.constructFragment(LayoutBuilder.java:150) 
    at org.robolectric.res.builder.LayoutBuilder.create(LayoutBuilder.java:104) 
    at org.robolectric.res.builder.LayoutBuilder.doInflate(LayoutBuilder.java:42) 
    at org.robolectric.res.builder.LayoutBuilder.doInflate(LayoutBuilder.java:45) 
    at org.robolectric.res.builder.LayoutBuilder.inflateView(LayoutBuilder.java:62) 
    at org.robolectric.shadows.ShadowLayoutInflater.inflate(ShadowLayoutInflater.java:50) 
    at org.robolectric.shadows.ShadowLayoutInflater.inflate(ShadowLayoutInflater.java:55) 
    at android.view.LayoutInflater.inflate(LayoutInflater.java) 
    at com.squareup.test.ActionBarSherlockRobolectric.setContentView(ActionBarSherlockRobolectric.java:38) 
    at com.actionbarsherlock.app.SherlockFragmentActivity.setContentView(SherlockFragmentActivity.java:262) 
    at com.marcelopazzo.fragmentapplication.MainActivity.onCreate(MainActivity.java:13) 
    at com.marcelopazzo.fragmentapplication.MainActivityTest.setUp(MainActivityTest.java:33) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27) 
    at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:110) 
    at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:234) 
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:133) 
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:114) 
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:188) 
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:166) 
    at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:86) 
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:101) 
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:74) 

これは私が使用していたテストクラスである:

@RunWith(RobolectricTestRunner.class) 
public class MainActivityTest { 

    private MainActivity activity; 
    private TextView textView; 

    public static final String GREETINGS = "Hello world!"; 

    @Before 
    public void setUp() { 

     ActionBarSherlock.registerImplementation(ActionBarSherlockRobolectric.class); 
     ActionBarSherlock.unregisterImplementation(ActionBarSherlockNative.class); 
     ActionBarSherlock.unregisterImplementation(ActionBarSherlockCompat.class); 

     activity = new MainActivity(); 
     activity.onCreate(null); 

     textView = (TextView) activity.findViewById(R.id.hello); 
    } 

    @Test 
    public void shouldGreet() { 
     assertEquals(GREETINGS, textView.getText()); 
    } 
} 

をアプリケーションがデバイス上で正常に動作しています。

私はここで何が欠けていますか?

PS:また正方形/マスター(2.0アルファ3平方5)ブランチからコードをテストし、同じ問題を抱えて:完全なソースコードgithub

編集に利用可能です。 LayoutBuilder.constructFragmentを調べると、activity.getSupportFragmentManager().beginTransaction().add(fragment, tag).commit()がSherlockFragmentで機能しないため、fragment.getView()がnullを返す問題があると思います。

これを修正するために私の側で何かできるかどうかわかりません...私はすでにrobolectricの側でそれを修正できるかどうかチェックしています。

答えて

7

では動作しません。

MainActivity activity = Robolectric.buildActivity(MainActivity.class) 
            .create().get(); 

onCreate()の呼び出し中にメインルーパーが一時的に一時停止するように設定します。

+1

返事に感謝をあなたのFragment.onCreateViewメソッドを呼び出します。 2.0-rc1と2.0-rc2-SNAPSHOTでテストしました。組織でヌル \t android.view.ViewGroup.addViewで(ViewGroup.java:3187) android.view.ViewGroup.addViewで\t(ViewGroup.java:3170) \t:まだNPE のjava.lang.NullPointerExceptionを取得.robolectric.res.builder.LayoutBuilder.constructFragment(LayoutBuilder.java:150) – marcelopazzo

+0

更新されたコードを[github](https://github.com/marcelopazzo/RobolectricSample)にプッシュしました。また、これはActionBarSherlockに関連していないことがわかりました。私はandroid.support.v4.app.Fragmentを使用して同じエラーが発生しています。 – marcelopazzo

+0

問題はrobolectric 2.1で修正されました。 – marcelopazzo

0

私は、このソリューションに満足してないんだけど、それを動作させるための方法があります:

私の破片からonCreateViewが呼ばれなかったので、この方法fragment.getView()がnullを返すされています。メソッドmoveToStateからandroid.support.v4.app.FragmentManagerから呼び出す必要がありますが、f.mFromLayoutがfalseであったため、このメソッドは呼び出されませんでした。

f.mActivity = mActivity; 
f.mFragmentManager = mActivity.mFragments; 
f.mCalled = false; 
f.onAttach(mActivity); 
if (!f.mCalled) { 
    throw new SuperNotCalledException("Fragment " + f 
    + " did not call through to super.onAttach()"); 
} 
mActivity.onAttachFragment(f); 

if (!f.mRetaining) { 
    f.mCalled = false; 
    f.onCreate(f.mSavedFragmentState); 
    if (!f.mCalled) { 
     throw new SuperNotCalledException("Fragment " + f 
     + " did not call through to super.onCreate()"); 
    } 
} 
f.mRetaining = false; 
if (f.mFromLayout) { 
    // For fragments that are part of the content view 
    // layout, we need to instantiate the view immediately 
    // and the inflater will take care of adding it. 
    f.mView = f.onCreateView(f.getLayoutInflater(f.mSavedFragmentState), 
    null, f.mSavedFragmentState); 
    if (f.mView != null) { 
    f.mInnerView = f.mView; 
    f.mView = NoSaveStateFrameLayout.wrap(f.mView); 
    if (f.mHidden) f.mView.setVisibility(View.GONE); 
     f.onViewCreated(f.mView, f.mSavedFragmentState); 
    } else { 
     f.mInnerView = null; 
    } 
} 

あなたのフラグメントにonCreate方法をこのコードブロックを追加するのであれば、それは動作します。

Field field = Fragment.class.getDeclaredField("mFromLayout"); 
field.setAccessible(true); 
field.setBoolean(this, true); 
field.setAccessible(false); 

私は真の解決策、誰かが適切な解決策を見つける前に、それを動作させるための方法ではなく、言ったように。

[UPDATE]この方法は、あなたが頻繁にトリミングするいくつかのスケジューリング/オーダー・オブ・オペレーションの問題を修正Robolectric 2.0の新ActivityControllerがを、使用してみてくださいRobolectric 2.0決勝

3

Robolectric.buildActivity(YourActivityClass.class).attach().create().start().resume().get(); 
を呼び出すと、こんにちは@Xianに

+0

チップをありがとうございます。最初の呼び出し(ref:http://robolectric.org/activity-lifecycle/)のさまざまな組み合わせを試みましたが、これは私の場合に働く最小限の設定です: .create()。visible()。start()。get (); 以前は.create()。visible()。get()のみを使用していましたが、フラグメントのビューは作成されませんでした。 Robolectric 3.0。 –

関連する問題