Android Mockito-Kotlin 错误 - "Actually, there were zero interactions with this mock"
Android Mockito-Kotlin error - "Actually, there were zero interactions with this mock"
以下是我的ViewModel
class的测试代码。我的应用程序架构基于 MVI。基本上,我正在尝试模拟我的回购和状态 classes。在我下面写的测试函数中,当我从 API.
成功加载新闻列表时,我试图检查状态是否以正确的顺序更改
class NewsListViewModelTest {
//...
@get:Rule
val testSchedulerRule = RxTestSchedulerRule()
private lateinit var testSubject: NewsListViewModel
private val loadingState = NewsListState(state = State.LOADING)
private val newsRepo = mock<NewsRepository>()
private val observer = mock<Observer<NewsListState>>()
@Before
fun setUp() {
testSubject = NewsListViewModel(newsRepo)
testSubject.observableState.observeForever(observer)
}
@Test
fun `Given news list successfully loaded, when action LoadNewsList is received, then state contains news list`() {
// GIVEN
val newsList = listOf(News("title", "description", Date(), "image"))
val successState = NewsListState(newsList = newsList, state = State.DATA)
whenever(newsRepo.loadAll("keyword", 1, 1))
.thenReturn(Observable.just(newsList))
// WHEN
testSubject.dispatch(NewsListAction.LoadNewsList("keyword"))
testSchedulerRule.triggerActions()
// THEN
inOrder(observer) {
verify(observer).onChanged(loadingState)
verify(observer).onChanged(successState)
}
verifyNoMoreInteractions(observer)
}
}
但是,当我 运行 这个测试时,我在 inOrder(observer){ ... }
的第一行中收到以下错误:
Wanted but not invoked:
observer.onChanged(
NewsListState(newsList=[], state=LOADING, errorMessage=)
);
-> at [packagename].NewsListViewModelTest.Given news list failed to load, when action LoadNewsList is received, then state contains error(NewsListViewModelTest.kt:77)
Actually, there were zero interactions with this mock.
这些是我的测试依赖项:
testImplementation 'junit:junit:4.12'
testImplementation 'androidx.arch.core:core-testing:2.1.0'
testImplementation 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0'
这个错误可能是什么原因?
编辑 -- 我的RxTestSchedulerRule
class:
class RxTestSchedulerRule(private val testScheduler: TestScheduler = TestScheduler()) : Scheduler(),
TestRule {
override fun apply(base: Statement, description: Description?): Statement {
RxJavaPlugins.setIoSchedulerHandler { testScheduler }
RxJavaPlugins.setComputationSchedulerHandler { testScheduler }
RxJavaPlugins.setNewThreadSchedulerHandler { testScheduler }
RxJavaPlugins.setSingleSchedulerHandler { testScheduler }
RxAndroidPlugins.setInitMainThreadSchedulerHandler { Schedulers.trampoline() }
return base
}
override fun createWorker() = testScheduler.createWorker()
fun triggerActions() = testScheduler.triggerActions()
}
编辑 2 -- 我的调度函数:
fun dispatch(?) {
newsRepository.loadAll(keyword = it.keyword,
pageSize = pageSize,
page = page)
.subscribeOn(Schedulers.io())
.map<NewsListChange> { newsList ->
NewsListChange.Data(newsList) }
.defaultIfEmpty(NewsListChange.Data(emptyList()))
.onErrorReturn { throwable ->
NewsListChange.Error(throwable) }
.startWith(NewsListChange.Loading)
}
请尝试代替此行
whenever(newsRepo.loadAll("keyword", 1, 1))
.thenReturn(Observable.just(newsList))
放
whenever(newsRepo.loadAll(anyString(), anyInt(), anyInt()))
.thenReturn(Observable.just(newsList))
以下是我的ViewModel
class的测试代码。我的应用程序架构基于 MVI。基本上,我正在尝试模拟我的回购和状态 classes。在我下面写的测试函数中,当我从 API.
class NewsListViewModelTest {
//...
@get:Rule
val testSchedulerRule = RxTestSchedulerRule()
private lateinit var testSubject: NewsListViewModel
private val loadingState = NewsListState(state = State.LOADING)
private val newsRepo = mock<NewsRepository>()
private val observer = mock<Observer<NewsListState>>()
@Before
fun setUp() {
testSubject = NewsListViewModel(newsRepo)
testSubject.observableState.observeForever(observer)
}
@Test
fun `Given news list successfully loaded, when action LoadNewsList is received, then state contains news list`() {
// GIVEN
val newsList = listOf(News("title", "description", Date(), "image"))
val successState = NewsListState(newsList = newsList, state = State.DATA)
whenever(newsRepo.loadAll("keyword", 1, 1))
.thenReturn(Observable.just(newsList))
// WHEN
testSubject.dispatch(NewsListAction.LoadNewsList("keyword"))
testSchedulerRule.triggerActions()
// THEN
inOrder(observer) {
verify(observer).onChanged(loadingState)
verify(observer).onChanged(successState)
}
verifyNoMoreInteractions(observer)
}
}
但是,当我 运行 这个测试时,我在 inOrder(observer){ ... }
的第一行中收到以下错误:
Wanted but not invoked:
observer.onChanged(
NewsListState(newsList=[], state=LOADING, errorMessage=)
);
-> at [packagename].NewsListViewModelTest.Given news list failed to load, when action LoadNewsList is received, then state contains error(NewsListViewModelTest.kt:77)
Actually, there were zero interactions with this mock.
这些是我的测试依赖项:
testImplementation 'junit:junit:4.12'
testImplementation 'androidx.arch.core:core-testing:2.1.0'
testImplementation 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0'
这个错误可能是什么原因?
编辑 -- 我的RxTestSchedulerRule
class:
class RxTestSchedulerRule(private val testScheduler: TestScheduler = TestScheduler()) : Scheduler(),
TestRule {
override fun apply(base: Statement, description: Description?): Statement {
RxJavaPlugins.setIoSchedulerHandler { testScheduler }
RxJavaPlugins.setComputationSchedulerHandler { testScheduler }
RxJavaPlugins.setNewThreadSchedulerHandler { testScheduler }
RxJavaPlugins.setSingleSchedulerHandler { testScheduler }
RxAndroidPlugins.setInitMainThreadSchedulerHandler { Schedulers.trampoline() }
return base
}
override fun createWorker() = testScheduler.createWorker()
fun triggerActions() = testScheduler.triggerActions()
}
编辑 2 -- 我的调度函数:
fun dispatch(?) {
newsRepository.loadAll(keyword = it.keyword,
pageSize = pageSize,
page = page)
.subscribeOn(Schedulers.io())
.map<NewsListChange> { newsList ->
NewsListChange.Data(newsList) }
.defaultIfEmpty(NewsListChange.Data(emptyList()))
.onErrorReturn { throwable ->
NewsListChange.Error(throwable) }
.startWith(NewsListChange.Loading)
}
请尝试代替此行
whenever(newsRepo.loadAll("keyword", 1, 1))
.thenReturn(Observable.just(newsList))
放
whenever(newsRepo.loadAll(anyString(), anyInt(), anyInt()))
.thenReturn(Observable.just(newsList))