Issue
Inflating error while trying to use FragmentScenario
with launchFragment
and launchFragmentInContainer
if using material component in XML.
android.view.InflateException: Binary XML file line #41: Binary XML file line #41: Error inflating class <widget class>
Caused by: android.view.InflateException: Binary XML file line #41: Error inflating class <widget class>
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:334)
at android.view.LayoutInflater.createView(LayoutInflater.java:647)
at com.android.internal.policy.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:58)
at android.view.LayoutInflater.onCreateView(LayoutInflater.java:720)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:788)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:863)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
...
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:886)
at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1227)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1293)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:710)
at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2063)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1853)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1808)
at androidx.fragment.app.FragmentManagerImpl.execSingleAction(FragmentManagerImpl.java:1685)
at androidx.fragment.app.BackStackRecord.commitNow(BackStackRecord.java:554)
at androidx.fragment.app.testing.FragmentScenario$1.perform(FragmentScenario.java:308)
at androidx.fragment.app.testing.FragmentScenario$1.perform(FragmentScenario.java:286)
at androidx.test.core.app.ActivityScenario.lambda$onActivity$1$ActivityScenario(ActivityScenario.java:534)
at androidx.test.core.app.ActivityScenario$$Lambda$0.run(Unknown Source:4)
at android.app.Instrumentation$SyncRunnable.run(Instrumentation.java:2093)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Caused by: java.lang.UnsupportedOperationException: Failed to resolve attribute at index 5: TypedValue{t=0x2/d=0x7f03009f a=-1}
at android.content.res.TypedArray.getColorStateList(TypedArray.java:538)
at android.widget.TextView.<init>(TextView.java:1214)
at android.widget.Button.<init>(Button.java:166)
at android.widget.Button.<init>(Button.java:141)
at android.widget.Button.<init>(Button.java:117)
Can't inflate XML because there are missing styles.
Solution
First of all be sure to have the latest fragment-testing
dependency:
debugImplementation "androidx.fragment:fragment-testing:$fragment_version"
Some additional info:
- The fix has been published in version
1.1.0-alpha03
, so prior versions will not work as described here. - Remember to use
debugImplementation
or the dependency will not work correctly, thanks to this so answer - If you have errors like
"process crashed, "No tests found.""
check if this issue can help.
After this you can create Fragments with:
val bundle = Bundle()
....
launchFragmentInContainer(bundle, R.style.Theme_AppCompat) {
YourFragment()
}
//proceed here with espresso testing
Don't forget
R.style.Theme_AppCompat
otherwise Espresso will crash with theandroid.view.InflateException
error if you use widgets coming from thecom.google.android.material:material
artifact. Obviously if you need a custom style you can add a new rule to your styles.xml and reference it here.
In my case I had the Navigation component configured so I had to follow the suggestion of the official documentation here to be sure the navController is ok with the lifecycle.
First of all I have create a generic method in my TestFragmentUtils.kt
inline fun <reified F : Fragment> launchFragmentScenario(
bundle: Bundle?, fragment: F, navController: NavController): FragmentScenario<F> {
return launchFragmentInContainer(bundle, R.style.Theme_AppCompat) {
fragment.also { fragment ->
fragment.viewLifecycleOwnerLiveData.observeForever { lifeCycleOwner ->
if (lifeCycleOwner != null) {
// The fragment’s view has just been created
Navigation.setViewNavController(fragment.requireView(), navController)
}
}
}
}
}
Then in my YourFragmentTest
i can create another method like:
private fun launchMyFragmentScenario(bundle: Bundle?): FragmentScenario<MyFragment>
//viewModel factory can be easily injected if you use FragmentFactory
= TestFragmentUtils.launchFragmentScenario(bundle, MyFragment(viewModelFactory), navController)
and call it before each test starts. (navController
param is mocked in @Before method)
Answered By - MatPag
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.