我正在使用 Junit & Mockito 4 对 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<DataState<List<TrendingResponse>>
,因此我无法获得应该是 dataObserver 的内容,以及我应该如何验证测试类中的 dataObserver。
Event os 开放类,用于处理 SingleLiveData 等事件
DataState 是包含 SUCCESS & FAILED 数据类的密封类
我已经编写了测试用例 livedata is likeLiveData<List<Response>
或类似的东西。