Android 如何使用 Robolectric 测试片段?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11333354/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I test fragments with Robolectric?
提问by kaneda
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 work.
我知道有一个Robolectric.shadowOf(Fragment)
方法和一个ShadowFragment
类,认为它们没有列在文档中,但我无法让它工作。
myFragment = new MyFragment();
myFragment.onCreateView(LayoutInflater.from(activity), (ViewGroup) activity.findViewById(R.id.container), null);
myFragment.onAttach(activity);
myFragment.onActivityCreated(null);
I'm working with API level 13 (Honeycomb).
我正在使用 API 级别 13 (Honeycomb)。
Thanks.
谢谢。
回答by colabug
Edit #4 & #5: In Robolectric 3.*, they split up the fragment starting functions.
编辑 #4 & #5:在Robolectric 3.* 中,他们拆分了片段启动功能。
For support fragments, you will need to add a dependencyto your build.gradle
:
对于支持片段,您将需要一个添加依赖关系到你build.gradle
:
testCompile "org.robolectric:shadows-supportv4:3.8"
Import: org.robolectric.shadows.support.v4.SupportFragmentTestUtil.startFragment;
进口: org.robolectric.shadows.support.v4.SupportFragmentTestUtil.startFragment;
For platform fragments, you don't need this dependency. Import: import static org.robolectric.util.FragmentTestUtil.startFragment;
对于平台片段,您不需要此依赖项。进口:import static org.robolectric.util.FragmentTestUtil.startFragment;
They both use the same name of startFragment()
.
它们都使用相同的名称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.
编辑 #3:Robolectric 2.4 有一个用于支持和常规片段的API。newInstance()
在构造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):
编辑 #2:如果您使用支持片段(支持常规活动/片段的应该在下一个版本中),则会有一个新的助手:
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:
编辑:如果您升级到 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();
}
}
回答by Brian Griffey
You guys are all doing this the hard way. Just use FragmentTestUtil.
你们都在以艰难的方式做这件事。只需使用 FragmentTestUtil。
FragmentTestUtil.startFragment(yourfragment);
回答by Baker
Support fragments have been moved to module:
支持片段已移至模块:
shadows-support-v4
阴影支持-v4
(as of July,2015, Robolectric v3.0)
(截至2015年7月,Robolectric v3.0)
Add a gradle dependency to app/build.gradle:
向 app/build.gradle 添加 gradle 依赖项:
testCompile 'org.robolectric:shadows-support-v4:3.0'
Then import to your Robolectric test java class:
然后导入到您的 Robolectric 测试 java 类:
import org.robolectric.shadows.support.v4.SupportFragmentTestUtil;
Then you can start & use a support-v4 fragment for testing:
然后您可以开始并使用 support-v4 片段进行测试:
@Test
public void minimalFragmentTest() throws Exception {
MyFunFragment fragment = new MyFunFragment();
SupportFragmentTestUtil.startVisibleFragment(fragment);
assertThat(fragment.getView()).isNotNull();
}
References:
参考:
- github changelog, moving support fragments to different module
- github changelog,将支持片段移动到不同的模块
回答by Christopher Perry
I'm pretty sure you have to create a FragmentTransaction
using the FragmentManager
, then it will work.
我敢肯定,你必须创建一个FragmentTransaction
使用FragmentManager
,那么它会工作。
回答by superjugy
I just wanted to add that in Robolectric 2.0 even after doing:
我只是想在 Robolectric 2.0 中添加它,即使在这样做之后:
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.
它仍然为我返回 null。我所做的是添加activity.getSupportFragmentManager().executePendingTransaction();
并且它起作用了。
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:
由于某种原因,robolectric 似乎没有运行它。似乎可能是 Looper 暂停了或者什么的。无论如何这对我有用,它看起来像这样:
activity = Robolectric.buildActivity(FragmentActivity.class).create().start().resume().get();
fragment.show(activity.getSupportFragmentManager(), null);
activity.getSupportFragmentManager().executePendingTransactions();
fragment.getDialog();
回答by prijupaul
SupportFragmentTestUtil.startFragment(fragment, AppCompatActivity::class.java)
If the activity is extending AppCompatActivity
如果活动延长 AppCompatActivity
This is using Kotlin
这是使用 Kotlin
回答by Link182
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
旧的 android 片段已经被弃用,似乎支持片段很快也会被弃用。要测试 androidx 片段,您可以使用带有 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)
}