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
我有以下活动,我想单元测试片段已经附加的情况,并且应该返回非null。并且应该落入其他条件:
这是我的活动:
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");
}
}
}
测试类是这样的:我可以编写测试来附加一个片段,但我想在片段已经附加时测试条件并且应该返回非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 */
}
}
感谢您的任何建议,
答案 0 :(得分:8)
方法you've chosen(使用recreate()
)只要复制您请求的行为就会有效。我相信这是最简单的方法。
尽管如此,我不能认为它是一个纯粹的单元测试,因为实际上你是在作弊,因为很明显你对这个活动的
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)
}
测试非空案例:
{{1}}
答案 1 :(得分:3)
我通过调用activity.recreate()
设法做到这一点@Test
fun testBillingFragmentAlreadyAttached() {
billingActivity.recreate()
val actualFragment = billingActivity
.supportFragmentManager
.findFragmentByTag(BillingView.TAG)
assertThat(actualFragment.tag, `is`(BillingView.TAG))
}
但如果有人有更好的方法。听听另一种解决方案会很好。