测试片段:我一直得到java.lang.RuntimeException:android.view.InflateException

测试片段:我一直得到java.lang.RuntimeException:android.view.InflateException,android,android-fragments,junit,android-espresso,android-instrumentation,Android,Android Fragments,Junit,Android Espresso,Android Instrumentation,我一直在关注材料组件,完成后我想我应该练习编写一些仪器测试。该应用程序运行良好。但是,当我运行任何测试时,都会出现此错误: java.lang.RuntimeException: android.view.InflateException: Binary XML file line #37: Binary XML file line #37: Error inflating class com.google.android.material.textfield.Tex

我一直在关注材料组件,完成后我想我应该练习编写一些仪器测试。该应用程序运行良好。但是,当我运行任何测试时,都会出现此错误:

    java.lang.RuntimeException: android.view.InflateException: Binary XML file line #37: Binary 
    XML file line #37: Error inflating class 
    com.google.android.material.textfield.TextInputLayout
    at androidx.test.runner.MonitoringInstrumentation.runOnMainSync(MonitoringInstrumentation.java:450)
    at androidx.test.core.app.ActivityScenario.onActivity(ActivityScenario.java:564)
    at androidx.fragment.app.testing.FragmentScenario.internalLaunch(FragmentScenario.java:300)
    at androidx.fragment.app.testing.FragmentScenario.launchInContainer(FragmentScenario.java:282)
    at com.google.codelabs.mdc.kotlin.shrine.LoginFragmentTest.username_and_password_editTexts_visible(LoginFragmentTest.kt:64)
    at java.lang.reflect.Method.invoke(Native Method)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:27)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
    at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
    at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:395)
    at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1941)
    Caused by: android.view.InflateException: Binary XML file line #37: Binary XML file line #37: Error inflating class com.google.android.material.textfield.TextInputLayout
    Caused by: android.view.InflateException: Binary XML file line #37: Error inflating class com.google.android.material.textfield.TextInputLayout
    Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Constructor.newInstance0(Native Method)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:430)
    at android.view.LayoutInflater.createView(LayoutInflater.java:645)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:787)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:727)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:858)
    at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:861)
    at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:518)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
    at com.google.codelabs.mdc.kotlin.shrine.LoginFragment.onCreateView(LoginFragment.kt:19)
    at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2698)
    at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:320)
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1187)
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
    at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
    at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497)
    at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:447)
    at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2169)
    at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1992)
    at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1947)
    at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1818)
    at androidx.fragment.app.BackStackRecord.commitNow(BackStackRecord.java:297)
    at androidx.fragment.app.testing.FragmentScenario$1.perform(FragmentScenario.java:317)
    at androidx.fragment.app.testing.FragmentScenario$1.perform(FragmentScenario.java:301)
    at androidx.test.core.app.ActivityScenario.lambda$onActivity$2$ActivityScenario(ActivityScenario.java:551)
    at androidx.test.core.app.ActivityScenario$$Lambda$4.run(Unknown Source)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at android.app.Instrumentation$SyncRunnable.run(Instrumentation.java:1959)
    at android.os.Handler.handleCallback(Handler.java:751)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6236)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:891)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:781)
    Caused by: java.lang.IllegalArgumentException: The style on this component requires your app theme to be Theme.MaterialComponents (or a descendant).
    at com.google.android.material.internal.ThemeEnforcement.checkTheme(ThemeEnforcement.java:248)
    at com.google.android.material.internal.ThemeEnforcement.checkMaterialTheme(ThemeEnforcement.java:222)
    at com.google.android.material.internal.ThemeEnforcement.checkCompatibleTheme(ThemeEnforcement.java:150)
    at com.google.android.material.internal.ThemeEnforcement.obtainTintedStyledAttributes(ThemeEnforcement.java:120)
    at com.google.android.material.textfield.TextInputLayout.<init>(TextInputLayout.java:424)
    at com.google.android.material.textfield.TextInputLayout.<init>(TextInputLayout.java:396)
    ... 38 more

    Test running failed: Instrumentation run failed due to 'Process crashed.'
我尝试更改材质依赖项的版本,但没有成功

我的样式文件

    <style name="AppTheme.NoActionBar" parent="Theme.MaterialComponents.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

这是因为您试图在创建视图之前访问它们。执行此操作:将视图的所有逻辑放在onViewCreated方法中,并将onCreateView保持如下状态

override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
   return inflater.inflate(R.layout.shr_login_fragment, container, false)

}
然后onViewCreated执行以下操作:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
next_button.setOnClickListener {
        //your logic
    }
    password_edit_text.setOnKeyListener { _, _, _ ->
        if(isPasswordValid(password_edit_text.text)){
            view.password_text_input.error = null
        }
        false
    }
    cancel_button.setOnClickListener {
        view.password_edit_text.setText("")
        view.username_edit_text.setText("")
    }

}
这就是问题所在:

原因:java.lang.IllegalArgumentException:此组件上的样式要求应用程序主题为theme.MaterialComponents(或其后代)。

我们需要为片段测试类提供正确的样式。在布局文件中,有材质组件视图(TextInputLayout),因此我们需要使用MaterialComponents主题

创建FragmentTest类时,请使用
style
参数:

@RunWith(AndroidJUnit4::class)
class DummyFragmentTest {

    @Test
    fun testing() {
        launchFragmentInContainer<DummyFragment>(factory = object : FragmentFactory() {
            override fun instantiate(classLoader: ClassLoader, className: String): Fragment {
                return DummyFragment()
            }
        }, themeResId = R.style.AppTheme.NoActionBar) // this is your style
    }
}
@RunWith(AndroidJUnit4::class)
类DummyFragmentTest{
@试验
趣味测试(){
launchFragmentInContainer(工厂=对象:FragmentFactory(){
重写有趣的实例化(classLoader:classLoader,className:String):片段{
返回DummyFragment()
}
},themeResId=R.style.AppTheme.NoActionBar)//这是您的样式
}
}
快速简便的修复方法

@之前
趣味设置(){
场景=启动片段(themeResId=R.style.Theme\u MaterialComponents)
}

你能发布你的片段实现吗?@MateoHervas添加了它:)我尝试了这一方法以获得更清晰的代码,但正如我已经提到的,应用程序运行正常,问题在于测试。
override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
   return inflater.inflate(R.layout.shr_login_fragment, container, false)

}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
next_button.setOnClickListener {
        //your logic
    }
    password_edit_text.setOnKeyListener { _, _, _ ->
        if(isPasswordValid(password_edit_text.text)){
            view.password_text_input.error = null
        }
        false
    }
    cancel_button.setOnClickListener {
        view.password_edit_text.setText("")
        view.username_edit_text.setText("")
    }

}
@RunWith(AndroidJUnit4::class)
class DummyFragmentTest {

    @Test
    fun testing() {
        launchFragmentInContainer<DummyFragment>(factory = object : FragmentFactory() {
            override fun instantiate(classLoader: ClassLoader, className: String): Fragment {
                return DummyFragment()
            }
        }, themeResId = R.style.AppTheme.NoActionBar) // this is your style
    }
}
    @Before
    fun setUp() {
        scenario = launchFragment<MyFragment>(themeResId = R.style.Theme_MaterialComponents)
    }