How to correctly mock ViewModel on androidTest

后端 未结 4 2106
野性不改
野性不改 2021-02-13 03:21

I\'m currently writing some UI unit tests for a fragment, and one of these @Test is to see if a list of objects is correctly displayed, this is not an integ

4条回答
  •  难免孤独
    2021-02-13 03:59

    Look like, you use kotlin and koin(1.0-beta). It is my decision for mocking

    @RunWith(AndroidJUnit4::class)
    class DashboardFragmentTest : KoinTest {
    @Rule
    @JvmField
    val activityRule = ActivityTestRule(SingleFragmentActivity::class.java, true, true)
    @Rule
    @JvmField
    val executorRule = TaskExecutorWithIdlingResourceRule()
    @Rule
    @JvmField
    val countingAppExecutors = CountingAppExecutorsRule()
    
    private val testFragment = DashboardFragment()
    
    private lateinit var dashboardViewModel: DashboardViewModel
    private lateinit var router: Router
    
    private val devicesSuccess = MutableLiveData>()
    private val devicesFailure = MutableLiveData()
    
    @Before
    fun setUp() {
        dashboardViewModel = Mockito.mock(DashboardViewModel::class.java)
        Mockito.`when`(dashboardViewModel.devicesSuccess).thenReturn(devicesSuccess)
        Mockito.`when`(dashboardViewModel.devicesFailure).thenReturn(devicesFailure)
        Mockito.`when`(dashboardViewModel.getDevices()).thenAnswer { _ -> Any() }
    
        router = Mockito.mock(Router::class.java)
        Mockito.`when`(router.loginActivity(activityRule.activity)).thenAnswer { _ -> Any() }
    
        StandAloneContext.loadKoinModules(hsApp + hsViewModel + api + listOf(module {
            single(override = true) { router }
            factory(override = true) { dashboardViewModel } bind ViewModel::class
        }))
    
        activityRule.activity.setFragment(testFragment)
        EspressoTestUtil.disableProgressBarAnimations(activityRule)
    }
    
    @After
    fun tearDown() {
        activityRule.finishActivity()
        StandAloneContext.closeKoin()
    }
    
    @Test
    fun devicesSuccess(){
        val list = listOf(Device(deviceName = "name1Item"), Device(deviceName = "name2"), Device(deviceName = "name3"))
        devicesSuccess.postValue(list)
        onView(withId(R.id.rv_devices)).check(ViewAssertions.matches(ViewMatchers.isCompletelyDisplayed()))
        onView(withId(R.id.rv_devices)).check(matches(hasDescendant(withText("name1Item"))))
        onView(withId(R.id.rv_devices)).check(matches(hasDescendant(withText("name2"))))
        onView(withId(R.id.rv_devices)).check(matches(hasDescendant(withText("name3"))))
    }
    
    @Test
    fun devicesFailure(){
        devicesFailure.postValue("error")
        onView(withId(R.id.rv_devices)).check(ViewAssertions.matches(ViewMatchers.isCompletelyDisplayed()))
        Mockito.verify(router, times(1)).loginActivity(testFragment.activity!!)
    }
    
    @Test
    fun devicesCall() {
        onView(withId(R.id.rv_devices)).check(ViewAssertions.matches(ViewMatchers.isCompletelyDisplayed()))
        Mockito.verify(dashboardViewModel, Mockito.times(1)).getDevices()
    }
    

    }

提交回复
热议问题