Исключение IllegalStateException при вызове getString() внутри класса фрагмента при модульном тестировании с помощью Robolectric

#java #android #unit-testing #kotlin #robolectric

Вопрос:

Я получаю исключение IllegalStateException, когда getString() вызывается внутри класса фрагмента

 Caused by: java.lang.IllegalStateException: Fragment SomeFragment{1df37025} (29efd1d0-77c1-4293-a0f6-b808c7559cf4)} not attached to a context.
at androidx.fragment.app.Fragment.requireContext(Fragment.java:805)
at androidx.fragment.app.Fragment.getResources(Fragment.java:869)
at androidx.fragment.app.Fragment.getString(Fragment.java:891)
 

Некоторый фрагмент кода

 public void someMethod() {
    getString(R.string.some_res)
}
 

Тестовый код

 @Before
fun setUp() {
    val activity = Robolectric.buildActivity(SomeActivity::class.java).create().get()
    fragment = SomeFragment()
    fragmentManager = activity.supportFragmentManager
    val fragmentTransaction: FragmentTransaction = fragmentManager.beginTransaction()
    fragmentTransaction.add(fragment, null)
    fragmentTransaction.commit()
}

@Test
@Throws(Exception::class)
fun someTest() {
    fragment.someMethod()
}
 

Комментарии:

1. можете ли вы попробовать commitNowAllowingStateLoss() ?

2. commitNowAllowingStateLoss() приводит к другой ошибке. java.lang.IllegalStateException: Fragment did not return a View from onCreateView() or this was called before onCreateView().

3. @cutiko commitNowAllowingStateLoss() решает проблему 🙂 Вы можете использовать это в качестве ответа для лучшего открытия.

4. Добавлено с некоторыми ссылками на документацию и объяснениями для соответствия стандартам SO, рад, что это сработало @MadhurGupta

Ответ №1:

Я думаю, что проблема может быть fragmentTransaction.commit() в том, что commit она асинхронна, поэтому при someTest() запуске фиксация могла закончиться или нет. В документации говорится:

Фиксация происходит не сразу

Замена commit для commitNow устранения или commitNowAllowingStateLoss должна устранить проблему. Из той же документации, приведенной выше, commit метод:

Фиксирует эту транзакцию синхронно