Robolectric 尝试扩充具有 TextInputLayout 的布局时测试失败
Robolectric test fails when trying to inflate layout that has a TextInputLayout
Android Studio 4.0.1
Robolectric 4.3.1
我正在编写 robolectric 测试,测试将失败并显示以下错误。而且好像和不能充气的TextInputLayout有关。如果我删除 TextInputLayout,测试将正常通过。
这是我收到的错误消息。
android.view.InflateException: Binary XML file line #47: Binary XML file line #47: Error inflating class com.google.android.material.textfield.TextInputLayout
Caused by: android.view.InflateException: Binary XML file line #47: Error inflating class com.google.android.material.textfield.TextInputLayout
Caused by: java.lang.IllegalArgumentException: The style on this component requires your app theme to be Theme.AppCompat (or a descendant).
测试class本身
@Config(sdk = [Build.VERSION_CODES.O_MR1])
@RunWith(AndroidJUnit4::class)
class CharitiesAdapterTest {
private lateinit var charitiesAdapter: CharitiesAdapter
@Before
fun setUp() {
charitiesAdapter = CharitiesAdapter()
}
@Test
fun `should create viewHolder`() {
// Act & Assert
assertThat(createViewHolder()).isNotNull
}
private fun createViewHolder(): CharitiesViewHolder {
val constraintLayout = ConstraintLayout(ApplicationProvider.getApplicationContext())
return charitiesAdapter.onCreateViewHolder(constraintLayout, 0)
}
}
实际测试中的适配器
class CharitiesAdapter : RecyclerView.Adapter<CharitiesViewHolder>() {
private val charitiesList: MutableList<Charity> = mutableListOf()
private var selectedCharity: (Charity) -> Unit = {}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CharitiesViewHolder {
val charitiesViewHolder = CharitiesViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.charity_item, parent, false))
return charitiesViewHolder
}
override fun getItemCount(): Int = charitiesList.count()
override fun onBindViewHolder(holder: CharitiesViewHolder, position: Int) {
// left blank
}
}
这是布局的一部分有问题。当仅删除 TextInputLayout 时,测试将通过 OK
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/textInputLayoutPostcode"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/ivLogo">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/editTextPostcode"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</com.google.android.material.textfield.TextInputLayout>
这是我正在使用的样式
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
感谢任何建议
您可以将测试配置为使用使用应用主题的模拟应用程序,如下所示:
Kotlin 实现
class TestApplication : Application() {
override fun onCreate() {
super.onCreate()
setTheme(R.style.AppTheme) //or just R.style.Theme_AppCompat
}
}
然后配置您的测试以使用此模拟应用程序
@Config(application=TestApplication::class, sdk = [Build.VERSION_CODES.O_MR1])
@RunWith(AndroidJUnit4::class)
class CharitiesAdapterTest {
Java 实施
public class TestApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
setTheme(R.style.AppTheme); //or just R.style.Theme_AppCompat
}
}
然后配置您的测试以使用此模拟应用程序
@Config(application=TestApplication.class, sdk = [Build.VERSION_CODES.O_MR1])
@RunWith(AndroidJUnit4.class)
class CharitiesAdapterTest {
你传错了Context
class:ApplicationProvider.getApplicationContext()
.
ApplicationContext
根本没有主题,使用 Activity
的 Context
建议(它将始终具有当前 Activity
的主题,无论哪个 Activity
或 Theme
是)。根据提供的代码,不清楚您如何启动 Activity
(Context
应该可以访问)。
使用 ActivityScenario
or ActivityScenarioRule
might be the proper way to do it.
The documentation shows how it works: AndroidX Test & JUnit4 rules with AndroidX Test 进行测试。
Android Studio 4.0.1
Robolectric 4.3.1
我正在编写 robolectric 测试,测试将失败并显示以下错误。而且好像和不能充气的TextInputLayout有关。如果我删除 TextInputLayout,测试将正常通过。
这是我收到的错误消息。
android.view.InflateException: Binary XML file line #47: Binary XML file line #47: Error inflating class com.google.android.material.textfield.TextInputLayout
Caused by: android.view.InflateException: Binary XML file line #47: Error inflating class com.google.android.material.textfield.TextInputLayout
Caused by: java.lang.IllegalArgumentException: The style on this component requires your app theme to be Theme.AppCompat (or a descendant).
测试class本身
@Config(sdk = [Build.VERSION_CODES.O_MR1])
@RunWith(AndroidJUnit4::class)
class CharitiesAdapterTest {
private lateinit var charitiesAdapter: CharitiesAdapter
@Before
fun setUp() {
charitiesAdapter = CharitiesAdapter()
}
@Test
fun `should create viewHolder`() {
// Act & Assert
assertThat(createViewHolder()).isNotNull
}
private fun createViewHolder(): CharitiesViewHolder {
val constraintLayout = ConstraintLayout(ApplicationProvider.getApplicationContext())
return charitiesAdapter.onCreateViewHolder(constraintLayout, 0)
}
}
实际测试中的适配器
class CharitiesAdapter : RecyclerView.Adapter<CharitiesViewHolder>() {
private val charitiesList: MutableList<Charity> = mutableListOf()
private var selectedCharity: (Charity) -> Unit = {}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CharitiesViewHolder {
val charitiesViewHolder = CharitiesViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.charity_item, parent, false))
return charitiesViewHolder
}
override fun getItemCount(): Int = charitiesList.count()
override fun onBindViewHolder(holder: CharitiesViewHolder, position: Int) {
// left blank
}
}
这是布局的一部分有问题。当仅删除 TextInputLayout 时,测试将通过 OK
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/textInputLayoutPostcode"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/ivLogo">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/editTextPostcode"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</com.google.android.material.textfield.TextInputLayout>
这是我正在使用的样式
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
感谢任何建议
您可以将测试配置为使用使用应用主题的模拟应用程序,如下所示:
Kotlin 实现
class TestApplication : Application() {
override fun onCreate() {
super.onCreate()
setTheme(R.style.AppTheme) //or just R.style.Theme_AppCompat
}
}
然后配置您的测试以使用此模拟应用程序
@Config(application=TestApplication::class, sdk = [Build.VERSION_CODES.O_MR1])
@RunWith(AndroidJUnit4::class)
class CharitiesAdapterTest {
Java 实施
public class TestApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
setTheme(R.style.AppTheme); //or just R.style.Theme_AppCompat
}
}
然后配置您的测试以使用此模拟应用程序
@Config(application=TestApplication.class, sdk = [Build.VERSION_CODES.O_MR1])
@RunWith(AndroidJUnit4.class)
class CharitiesAdapterTest {
你传错了Context
class:ApplicationProvider.getApplicationContext()
.
ApplicationContext
根本没有主题,使用 Activity
的 Context
建议(它将始终具有当前 Activity
的主题,无论哪个 Activity
或 Theme
是)。根据提供的代码,不清楚您如何启动 Activity
(Context
应该可以访问)。
使用 ActivityScenario
or ActivityScenarioRule
might be the proper way to do it.
The documentation shows how it works: AndroidX Test & JUnit4 rules with AndroidX Test 进行测试。