有没有办法将 Class 变量传递给 Espresso ActivityTestRule?

Is there a way to pass a Class variable to Espresso ActivityTestRule?

我正在使用 Espresso 为活动编写测试。对于每个 activity,测试看起来像这样

@RunWith(AndroidJUnit4::class)
class TestSomeActivity {
    @get:Rule
    var activityTestRule = ActivityTestRule(SomeActivity::class.java, true, false)
    @Test
    fun testNullIntent() {
        val intent = Intent()
        activityTestRule.launchActivity(intent)
    }
}

每当 Activity 调用 intent.getExtranull 的 Intent 返回时,它所做的就是返回。

问题是,如果我们要对每个 activity 进行检查,则必须编写相同的代码,除了这一行 -

@get:Rule
var activityTestRule = ActivityTestRule(SomeActivity::class.java, true, false)

为了解决这个问题,我使用 PackageManager 获取了所有活动的名称并将它们转换为 Class。然后我尝试将此 class 传递给我的 activityTestRule.

val intent = Intent()
val activityInfoList = getAllActivities()
for(activityInfo in activityInfoList!!) {
    val className = activityInfo.applicationInfo.className
    val activityClass = Class.forName(className)
    val activityTestRule = ActivityTestRule(activityClass.javaClass, true, false)
    activityTestRule.launchActivity(intent)
}

不幸的是,这导致了编译时错误-

None of the following functions can be called with the arguments supplied.
<init>(SingleActivityFactory<T!>!, Boolean, Boolean)   where T cannot be inferred for    constructor ActivityTestRule<T : Activity!>(activityFactory: SingleActivityFactory<T!>!, initialTouchMode: Boolean, launchActivity: Boolean) defined in androidx.test.rule.ActivityTestRule
<init>(Class<T!>!, Boolean, Boolean)   where T cannot be inferred for    constructor ActivityTestRule<T : Activity!>(activityClass: Class<T!>!, initialTouchMode: Boolean, launchActivity: Boolean) defined in androidx.test.rule.ActivityTestRule

为了解决这个问题,我们尝试使用

将activityClass转换为Activity
val activityClass = Class.forName(className) as Activity
val activityTestRule = ActivityTestRule(activityUnderTest.javaClass, true, false)

消除了编译时错误但引入了java.lang.ClassCastException: java.lang.Class cannot be cast to android.app.Activity

有没有办法为 class 中的所有活动 运行 相同的 Espresso 脚本,或者将 Class 传递给 ActivityTestRule?

代替这段代码

val activityClass = Class.forName(className) as Activity

您可以使用以下

val activityClass = Class.forName(className) as Class<Activity>

这将确保您不会遇到编译时错误,并且在您 运行 您的代码之后不会发生类型转换异常。