Search code examples
androidandroid-espressoandroid-livedataandroid-architecture-navigation

Waiting for livedata to complete in UI Espresso test


I'm new to testing and Espresso, so bear with me please.

I have an app with some simple image editing and I have decided to cover it with UI tests. For starters I have decided to test the initial image uploading, processing and moving to the next screen.

here is the test I came up with so far:

@LargeTest
@RunWith(AndroidJUnit4::class)
class VerifyLoadImage {
    lateinit var testContext: Context

    @Rule
    @JvmField
    var mActivityTestRule = ActivityScenarioRule(MainActivity::class.java)

    @Before
    fun loadContext() {
        testContext = InstrumentationRegistry.getInstrumentation().context
    }

    @Test
    fun loadImageToCrop() {
        mActivityTestRule.scenario.onActivity { mainActivity ->

// get the activity

            val navigationFragment = mainActivity.supportFragmentManager.findFragmentById(R.id.fragmentContainer)

//verify that current fragment displayed is ImagePickerFragment
            val currentFragment = navigationFragment?.getDisplayedChildFragment()?.let { it as? ImagePickerFragment }
                ?: throw AssertionError("currentFragment is not instance of ImagePickerFragment")

//call the method to upload the image from input stream, process it and then navigate to the crop screen
            currentFragment.loadBitmapAndOpenCropScreen(AssetInputStreamProvider(testContext, "sample_image.jpg"))

//verify that crop screen is currently displayed
            assert(navigationFragment.getDisplayedChildFragment() is CropFragment)
        }
    }
}

private fun Fragment.getDisplayedChildFragment() = childFragmentManager.fragments.first()

this is the code in currentFragment.loadBitmapAndOpenCropScreen

    internal fun loadBitmapAndOpenCropScreen(inputStreamProvider: InputStreamProvider) {
        activityViewModel.loadBitmap(inputStreamProvider).observe(viewLifecycleOwner) {
            when (it) {
                Loading -> showLoading()
                is Success -> {
                    hideLoading()
                    findNavController().navigate(ImagePickerFragmentDirections.toCrop())
                }
                is Error -> hideLoading()
            }
        }
    }

the problem is that when testing, the LiveData never changes updates at all [works normally when launching the app].

I would appreciate any help here.


Solution

  • Try InstantTaskExecutorRule

    @Rule
    @JvmField
    var mInstantTaskExecutorRule = InstantTaskExecutorRule()