Friday, 16 April 2021

Robolectric start a fragment that has an observer

How to start a fragment with a LiveData observer in the test scope with Robolectric

Fragment

class MyFragment(private val viewModel: MyViewModel) : Fragment() {

    ...

    fun myObserver {
        ... 
        // If I remove this observer the test will pass. 
        viewModel.MyLiveData.observe(viewLifecycleOwner, Observer{
            ...
        }
    }
}

My Test uses the RobolectricTestRunner so I can launch the fragment in the test scope.

@RunWith(robolectricTestRunner::class) 
class MyFragmentTest {

    // Executes tasks in the Architecture Components in the same thread
    @get:Rule
    var instantTaskExecutorRule = InstantTaskExecutorRule()

    @Test
    fun testOne() {
        val viewModel: MyViewModel = mock(MyViewModel::class.java)
        val scenario = launchFragmentInContainer(
            factory = MainFragmentFactory(viewModel),
            fragmentArgs = null
            themeResId = R.style.Theme_MyTheme
        )
        // Tried implementing shadowOf as the error suggests. 

    } 
}

I get the following error when trying to run the test. I've tried setting Main looper to idle before and after instantiating the FragmentScenario.

java.lang.Exception: Main looper has queued unexecuted runnables. This might be the cause of the test failure. You might need a shadowOf(getMainLooper()).idle() call.

I've tried the following

  • implementing a shadow class for the Main Looper. Annotating the class with Looper mode.
@RunWith(RobolectricTestRunner::class)
@LooperMode(LooperMode.Mode.PAUSED)
class MyFragmentTest {
  • Adding scenario states
    scenario.moveToState(Lifecycle.State.CREATED)
    scenario.moveToState(Lifecycle.State.RESUMED)

My Test dependencies.

    // Test
    testImplementation 'androidx.arch.core:core-testing:2.1.0'
    testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.4.3'
    testImplementation "androidx.test.ext:junit-ktx:1.1.2"
    testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.4.3"
    testImplementation 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0'
    testImplementation 'junit:junit:4.13.2'
    testImplementation 'androidx.test.espresso:espresso-core:3.3.0'
    testImplementation "org.robolectric:robolectric:4.5.1"
    testImplementation "org.mockito:mockito-android:2.28.2"

    // Testing Fragments
    debugImplementation "androidx.fragment:fragment-testing:1.3.2"

Links I've used to find a solution' Testing LiveData Transformations?



from Robolectric start a fragment that has an observer

No comments:

Post a Comment