Android Studio 3.2 Canary 2
Build #AI-173.4591728, built on February 8, 2018
JRE: 1.8.0_152-release-1024-b01 amd64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Linux 4.14.18-300.fc27.x86_64
我有以下 Activity ,我想对 fragment 已连接的情况进行单元测试,并应返回非null值。并且应该落入else条件:
这是我的 Activity :
public class BillingActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.billing_container);
if(getSupportFragmentManager().findFragmentByTag(BillingView.TAG) == null) {
final FragmentTransaction fragmentTransaction =
getSupportFragmentManager().beginTransaction();
fragmentTransaction.add(
R.id.billing_view_container,
BillingView.newInstance(),
BillingView.TAG);
fragmentTransaction.commit();
}
else {
Timber.d("Fragment already attached");
}
}
}
测试类是这样的:我可以编写测试来附加一个 fragment ,但是当 fragment 已经附加并且应该返回非null时,我想测试条件。
class BillingActivityTest: BaseRobolectricTestRunner() {
private lateinit var billingActivity: BillingActivity
@Before
fun setup() {
billingActivity = Robolectric.buildActivity(BillingActivity::class.java)
.create()
.start()
.get()
}
@Test
fun testBillingActivityIsNotNullValue() {
assertThat(billingActivity, `is`(notNullValue()))
}
@Test
fun testBillingFragmentHasStarted() {
val actualFragment = billingActivity
.supportFragmentManager
.findFragmentByTag(BillingView.TAG)
assertThat(actualFragment.tag, `is`(BillingView.TAG))
}
@Test
fun testBillingFragmentAlreadyAttached() {
/* how to test */
}
}
感谢您的任何建议,
最佳答案
只要方法you've chosen(使用 recreate()
)能够复制您所请求的行为,它将起作用。我相信这是目前为止最短的方法。
但是,我不能将其视为纯粹的单元测试,因为实际上您在作弊,因为显然您对 Activity 的recreate()
操作不感兴趣(这也可能会有副作用)。
如果您要执行纯单元测试,那么这里是这样做的方法。宣布 Activity 为: class MainActivity : AppCompatActivity() { internal var fragmentManagerRetriever = FragmentManagerRetriever() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val fragmentManager = fragmentManagerRetriever.getFragmentManager(this) if (fragmentManager.findFragmentByTag("TAG") == null) { val fragmentTransaction = fragmentManager.beginTransaction() fragmentTransaction.add(SomeFragment(), "TAG") fragmentTransaction.commit() } } }
FragmentManagerRetriever
就是这样简单: class FragmentManagerRetriever { public FragmentManager getFragmentManager(FragmentActivity activity) { return activity.getSupportFragmentManager(); } }
然后,您就可以执行纯单元测试了: @Test fun nullCase() { val activityController = Robolectric.buildActivity(MainActivity::class.java) val activity = activityController.get() val fragmentManagerRetriever = mock(FragmentManagerRetriever::class.java) val fragmentManager = mock(FragmentManager::class.java) val fragmentTransaction = mock(FragmentTransaction::class.java) activity.fragmentManagerRetriever = fragmentManagerRetriever `when`(fragmentManagerRetriever.getFragmentManager(activity)).thenReturn(fragmentManager) `when`(fragmentManager.findFragmentByTag("TAG")).thenReturn(null) `when`(fragmentManager.beginTransaction()).thenReturn(fragmentTransaction) activityController.create() val inOrder = Mockito.inOrder(fragmentTransaction) inOrder.verify(fragmentTransaction).add(ArgumentMatchers.any(SomeFragment::class.java), ArgumentMatchers.eq("TAG")) inOrder.verify(fragmentTransaction).commit() }
并测试非空的情况: @Test fun nonNullCase() { val activityController = Robolectric.buildActivity(MainActivity::class.java) val activity = activityController.get() val fragmentManagerRetriever = mock(FragmentManagerRetriever::class.java) val fragmentManager = mock(FragmentManager::class.java) val fragmentTransaction = mock(FragmentTransaction::class.java) activity.fragmentManagerRetriever = fragmentManagerRetriever `when`(fragmentManagerRetriever.getFragmentManager(activity)).thenReturn(fragmentManager) `when`(fragmentManager.findFragmentByTag("TAG")).thenReturn(mock(Fragment::class.java)) activityController.create() verifyZeroInteractions(fragmentTransaction) }
关于android - findFragmentByTag的单元测试条件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48812927/