【问题标题】:Write unit Testcase for ViewModel in kotlin在 kotlin 中为 ViewModel 编写单元测试用例
【发布时间】:2019-10-03 19:46:02
【问题描述】:

我正在使用 Junit & Mockito 4 对 viewModel 进行单元测试。

ViewModel 类

class MainViewModel(app: Application, private val githubRepo: GithubRepository) :
    BaseViewModel(app) {


    private val _trendingLiveData by lazy { MutableLiveData<Event<DataState<List<TrendingResponse>>>>() }
    val trendingLiveData: LiveData<Event<DataState<List<TrendingResponse>>>> by lazy { _trendingLiveData }

    var loadingState = MutableLiveData<Boolean>()


    fun getTrendingData(language: String?, since: String?) {
        launch {
            loadingState.postValue(true)
            when (val result = githubRepo.getTrendingListAsync(language, since).awaitAndGet()) {
                is Result.Success -> {
                    loadingState.postValue(false)
                    result.body?.let {
                        Event(DataState.Success(it))
                    }.run(_trendingLiveData::postValue)
                }

                is Result.Failure -> {
                    loadingState.postValue(false)
                }
            }
        }
    }

}

API 端点

interface GithubRepository {

    fun getTrendingListAsync(
        language: String?,
        since: String?
    ): Deferred<Response<List<TrendingResponse>>>
}

ViewModel 测试类

@RunWith(JUnit4::class)
class MainViewModelTest {

    @Rule
    @JvmField
    val instantTaskExecutorRule = InstantTaskExecutorRule()

    @Mock
    lateinit var repo: GithubRepository

    @Mock
    lateinit var githubApi: GithubApi

    @Mock
    lateinit var application: TrendingApp
    lateinit var viewModel: MainViewModel

    @Mock
    lateinit var dataObserver: Observer<Event<DataState<List<TrendingResponse>>>>

    @Mock
    lateinit var loadingObserver: Observer<Boolean>

    private val threadContext = newSingleThreadContext("UI thread")
    private val trendingList : List<TrendingResponse> = listOf()


    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        Dispatchers.setMain(threadContext)
        viewModel = MainViewModel(application, repo)
    }


    @Test
    fun test_TrendingRepo_whenSuccess() {

        //Assemble
        Mockito.`when`(githubApi.getTrendingListAsync("java", "daily"))
            .thenAnswer{ return@thenAnswer trendingList.toDeferred() }

        //Act
        viewModel.trendingLiveData.observeForever(dataObserver)
        viewModel.loadingState.observeForever(loadingObserver)
        viewModel.getTrendingData("java", "daily")

        Thread.sleep(1000)

        //Verify
        verify(loadingObserver).onChanged(true)
        //verify(dataObserver).onChanged(trendingList)
        verify(loadingObserver).onChanged(false)


    }


    @After
    fun tearDown() {
        Dispatchers.resetMain()
        threadContext.close()
    }
}

问题是我的 livedata 包裹在 Event&lt;DataState&lt;List&lt;TrendingResponse&gt;&gt; 周围,因此我无法获得应该是 dataObserver 的内容,以及我应该如何在测试类中验证该 dataObserver。

Event os 开放类,用于处理 SingleLiveData 等事件

DataState 是包含 SUCCESS & FAILED 数据类的密封类

我已经编写了测试用例 livedata 就像 LiveData&lt;List&lt;Response&gt; 或类似的东西。

【问题讨论】:

  • 看起来你只需要打开你的类型来获取列表

标签: android unit-testing android-livedata android-viewmodel mockito-kotlin


【解决方案1】:

您需要包装 List&lt;TrendingResponse&gt; → Event(DataState.Success(List&lt;TrendingResponse&gt;)) 使用 mockito - trendingList.toDeferred() 返回。

@Test
fun test_TrendingRepo_whenSuccess() {

    //Assemble
    Mockito.`when`(githubApi.getTrendingListAsync("java", "daily"))
        .thenAnswer{ return@thenAnswer trendingList.toDeferred() }

    //Act
    viewModel.trendingLiveData.observeForever(dataObserver)
    viewModel.loadingState.observeForever(loadingObserver)
    viewModel.getTrendingData("java", "daily")

    Thread.sleep(1000)

    //Verify
    verify(loadingObserver).onChanged(true)
    //wrap the trendingList inside Event(DataState(YourList))
    verify(dataObserver).onChanged(Event(DataState.Success(trendingList)))
    verify(loadingObserver).onChanged(false)


}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多