аргументы фрагмента равны нулю при использовании launchFragmentInContainer - PullRequest
0 голосов
/ 01 августа 2020

Я пишу тест для фрагмента, который использует safeArgs и FragmentScenario, однако, когда я вызываю launchFragmentInContainer() с параметром fragmentArgs, я получаю исключение, в котором говорится, что аргументы равны нулю. В производственном коде нет проблем.

Мой график навигации:

<fragment
        android:id="@+id/fragmentNewListItems"
        android:name="com.hotmail.or_dvir.arislistkt2.vvm.FragmentNewListItems"
        android:label="@string/title_newItems"
        tools:layout="@layout/fragment_new_list_items">

        <argument
            android:name="listId"
            app:argType="string" />
        <argument
            android:name="listName"
            app:argType="string" />
    </fragment>

Мой тест:

class TesFragmentNewListItems : BaseAndroidTest() {
    private lateinit var fragScenario: FragmentScenario<FragmentNewListItems>

    private val list1 = UserList("list 1")

    @Before
    fun before() {
        //adding a user list to add items to
        repoUserLists.addLists(list1)
        fragScenario = this.launchFragment(
            //setting arguments here
            bundleOf("listId" to list1.id, "listName" to list1.name)
        )
    }


    inline fun <reified T : Fragment> launchFragment(args: Bundle): FragmentScenario<T> {
        return launchFragmentInContainer<T>(
            themeResId = R.style.AppTheme,
            fragmentArgs = args
        )
    }

когда я пытаюсь запустить тест, я получаю

Caused by: java.lang.IllegalArgumentException: Argument "listId" is marked as non-null but was passed a null value.

полная трассировка стека:

java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at androidx.test.runner.MonitoringInstrumentation.runOnMainSync(MonitoringInstrumentation.java:441)
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.hotmail.or_dvir.arislistkt2.TesFragmentNewListItems.before(TesFragmentNewListItems.kt:79)
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 androidx.test.internal.runner.junit4.statement.RunBefores.evaluate(RunBefores.java:76)
at androidx.test.internal.runner.junit4.statement.RunAfters.evaluate(RunAfters.java:61)
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
at org.koin.test.mock.MockProviderRule$apply$1.evaluate(MockProviderRule.kt:13)
at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
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:392)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2189)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at androidx.navigation.NavArgsLazy.getValue(NavArgsLazy.kt:52)
at androidx.navigation.NavArgsLazy.getValue(NavArgsLazy.kt:34)
at com.hotmail.or_dvir.arislistkt2.vvm.FragmentNewListItems.getFragArgs(Unknown Source:4)
at com.hotmail.or_dvir.arislistkt2.vvm.FragmentNewListItems.onViewCreated(FragmentNewListItems.kt:31)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:332)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1199)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1368)
at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1446)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1509)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:447)
at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2181)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2004)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1959)
at androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1830)
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:4)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.app.Instrumentation$SyncRunnable.run(Instrumentation.java:2207)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.lang.IllegalArgumentException: Argument "listId" is marked as non-null but was passed a null value.
at com.hotmail.or_dvir.arislistkt2.vvm.FragmentNewListItemsArgs$Companion.fromBundle(FragmentNewListItemsArgs.kt:28)
at com.hotmail.or_dvir.arislistkt2.vvm.FragmentNewListItemsArgs.fromBundle(Unknown Source:2)
... 30 more

Изменить:

Идентификатор List1 не равен нулю, поскольку он инициализируется в конструкторе.

class UserList(
    name: String
) : BaseItem(name) {

    //class body
}
abstract class BaseItem(
    var name: String,
    var id: UUID = UUID.randomUUID()
) {

    //class body
}

Ответы [ 2 ]

0 голосов
/ 10 августа 2020

разобрался. я почему-то пропустил это предупреждение:

W/Bundle: Key listId expected String but value was a java.util.UUID.  The default value <null> was returned.

все, что мне нужно было сделать, это изменить это bundleOf("listId" to list1.id...) на bundleOf("listId" to list1.id.toString()...) (добавлен вызов toString())

не уверен, почему Google выбрал обрабатывать недопустимые типы, превращая их в null вместо создания исключения InvalidParameter (или аналогичного).

0 голосов
/ 07 августа 2020

Из вашего поста непонятно, как выглядят классы UserList и repoUserLists. Как инициализируется id? Кажется, вы только передаете параметр для name конструктору UserList. repoUserLists выполняет инициализацию id?

Я предполагаю, что id на самом деле null, как указано в сообщении об исключении.

У вас есть инициализация id, которая работает только для производственных сборок, а не в тестовой среде?

Чтобы проверить это, вы должны добавить строку в свой метод before после строки

repoUserLists.addLists(list1)

который подтверждает, что list1.id на самом деле не null.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...