I know there is a Robolectric.shadowOf(Fragment)
method and a ShadowFragment
class, thought they aren\'t listed on the docs, but I can\'t make it w
Edit #4 & #5: In Robolectric 3.*, they split up the fragment starting functions.
For support fragments, you will need to add a dependency to your build.gradle
:
testCompile "org.robolectric:shadows-supportv4:3.8"
Import: org.robolectric.shadows.support.v4.SupportFragmentTestUtil.startFragment;
For platform fragments, you don't need this dependency. Import: import static org.robolectric.util.FragmentTestUtil.startFragment;
They both use the same name of startFragment()
.
import static org.robolectric.shadows.support.v4.SupportFragmentTestUtil.startFragment;
@RunWith(RobolectricTestRunner.class)
@Config(constants = BuildConfig.class)
public class YourFragmentTest
{
@Test
public void shouldNotBeNull() throws Exception
{
YourFragment fragment = YourFragment.newInstance();
startFragment( fragment );
assertNotNull( fragment );
}
}
Edit #3: Robolectric 2.4 has an API for support and regular fragments. You can either use the newInstance()
pattern or use the constructor when constructing your Fragment
's.
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.assertNotNull;
import static org.robolectric.util.FragmentTestUtil.startFragment;
@RunWith(RobolectricGradleTestRunner.class)
public class YourFragmentTest
{
@Test
public void shouldNotBeNull() throws Exception
{
YourFragment fragment = new YourFragment();
startFragment( fragment );
assertNotNull( fragment );
}
}
Edit #2: There's a new helper if you're using support fragments (one that supports regular activities/fragments should be in the next release):
import static org.robolectric.util.FragmentTestUtil.startFragment;
@Before
public void setUp() throws Exception
{
fragment = YourFragment.newInstance();
startFragment( fragment );
}
Edit: If you upgraded to Robolectric 2.0:
public static void startFragment( Fragment fragment )
{
FragmentActivity activity = Robolectric.buildActivity( FragmentActivity.class )
.create()
.start()
.resume()
.get();
FragmentManager fragmentManager = activity.getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add( fragment, null );
fragmentTransaction.commit();
}
Original answer
As the other commenter suggested, you do need to use the fragment manager (instead of calling the lifecycle methods you listed above).
@RunWith(MyTestRunner.class)
public class YourFragmentTest
{
@Test
public void shouldNotBeNull() throws Exception
{
YourFragment yourFragment = new YourFragment();
startFragment( yourFragment );
assertNotNull( yourFragment );
}
I create a test runner and have a function that starts up a fragment for me so I can use it everywhere.
public class MyTestRunner extends RobolectricTestRunner
{
public MyTestRunner( Class<?> testClass ) throws InitializationError
{
super( testClass );
}
public static void startFragment( Fragment fragment )
{
FragmentManager fragmentManager = new FragmentActivity().getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add( fragment, null );
fragmentTransaction.commit();
}
}
SupportFragmentTestUtil.startFragment(fragment, AppCompatActivity::class.java)
If the activity is extending AppCompatActivity
This is using Kotlin
Old android fragments are already deprecated, seems like support fragments soon will be deprecated too. To test androidx fragments you can use fragment scenarios with robolectric https://developer.android.com/training/basics/fragments/testing
testImplementation 'androidx.fragment:fragment-testing:1.2.2'
val scenario = launchFragmentInContainer<MyFragment>()
scenario.onFragment { fragment ->
assertNotNull(fragment.view.synteticInflatedView)
}
I just wanted to add that in Robolectric 2.0 even after doing:
activity = Robolectric.buildActivity(FragmentActivity.class).create().start().resume().get();
fragment.show(activity.getSupportFragmentManager(), null);
fragment.getDialog(); //This stills returns null
It still returned null for me. what I did was to add activity.getSupportFragmentManager().executePendingTransaction();
and it worked.
It seems robolectric doesn't run this for some reason. it seems that maybe the Looper is paused or something. any way this worked for me and it looks like this:
activity = Robolectric.buildActivity(FragmentActivity.class).create().start().resume().get();
fragment.show(activity.getSupportFragmentManager(), null);
activity.getSupportFragmentManager().executePendingTransactions();
fragment.getDialog();
I'm pretty sure you have to create a FragmentTransaction
using the FragmentManager
, then it will work.
Support fragments have been moved to module:
shadows-support-v4
(as of July,2015, Robolectric v3.0)
Add a gradle dependency to app/build.gradle:
testCompile 'org.robolectric:shadows-support-v4:3.0'
Then import to your Robolectric test java class:
import org.robolectric.shadows.support.v4.SupportFragmentTestUtil;
Then you can start & use a support-v4 fragment for testing:
@Test
public void minimalFragmentTest() throws Exception {
MyFunFragment fragment = new MyFunFragment();
SupportFragmentTestUtil.startVisibleFragment(fragment);
assertThat(fragment.getView()).isNotNull();
}
References: