Unit testing Mockito和Kotlin测试异步故障
我正在努力学习Mockito以备测试,但使用Kotlin时会更复杂。我想在我的presenter中测试一个函数,调用该函数时,异步从存储库获取对象列表,并从侦听器启动onSuccess/onError。之后,演示者告诉视图根据回调执行任何需要的操作 以下是测试代码:Unit testing Mockito和Kotlin测试异步故障,unit-testing,mockito,kotlin,Unit Testing,Mockito,Kotlin,我正在努力学习Mockito以备测试,但使用Kotlin时会更复杂。我想在我的presenter中测试一个函数,调用该函数时,异步从存储库获取对象列表,并从侦听器启动onSuccess/onError。之后,演示者告诉视图根据回调执行任何需要的操作 以下是测试代码: @Mock lateinit var view: CategoriesActivityContract.View @Mock lateinit var repository: CategoriesRepository @Befo
@Mock
lateinit var view: CategoriesActivityContract.View
@Mock
lateinit var repository: CategoriesRepository
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
}
@Test
fun shouldPassCategoriesToView2() {
`doAnswer`({
it: InvocationOnMock? ->
(it!!.arguments[0] as CategoriesRepository.OnGetCategoriesListener).onSuccess(DUMMY_CATEGORIES)
null
}).`when`(repository).getCategoriesAsync(any(CategoriesRepository.OnGetCategoriesListener::class.java))
val presenter: CategoriesActivityPresenter = CategoriesActivityPresenter(repository)
presenter.bindView(view)
presenter.loadCategories()
`verify`(view).displayCategories(DUMMY_CATEGORIES)
}
这是经过测试的代码:
override fun loadCategories() {
repository.getCategoriesAsync(object: CategoriesRepository.OnGetCategoriesListener {
override fun onSuccess(categories: List<Category>) {
if (!categories.isEmpty()) {
view?.displayCategories(categories)
} else {
view?.displayNoCategoriesError()
}
}
override fun onError(message: String?) {
view?.displayNoCategoriesError()
}
})
}
Mockito.any(Class)
返回null
(,),这是getCategoriesAsync
方法不接受的。您可以使用“不返回空值”的库来解决此问题。
Mockito.any(Class)
返回null
(,),这是getCategoriesAsync
方法不接受的。您可以使用“不返回空值”的库来解决此问题。免责声明:我是Mockito-Kotlin的作者。免责声明:我是Mockito-Kotlin的作者。
java.lang.IllegalStateException: any(CategoriesRepository…riesListener::class.java) must not be null
at com.boyukliev.verseattack.ui.categories.CategoriesActivityPresenterTest.shouldPassCategoriesToView2(CategoriesActivityPresenterTest.kt:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:68)
at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:74)
at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:161)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaced or misused argument matcher detected here:
-> at com.boyukliev.verseattack.ui.categories.CategoriesActivityPresenterTest.shouldPassCategoriesToView2(CategoriesActivityPresenterTest.kt:60)
You cannot use argument matchers outside of verification or stubbing.
Examples of correct usage of argument matchers:
when(mock.get(anyInt())).thenReturn(null);
doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject());
verify(mock).someMethod(contains("foo"))
This message may appear after an NullPointerException if the last matcher is returning an object
like any() but the stubbed method signature expect a primitive argument, in this case,
use primitive alternatives.
when(mock.get(any())); // bad use, will raise NPE
when(mock.get(anyInt())); // correct usage use
Also, this error might show up because you use argument matchers with methods that cannot be mocked.
Following methods *cannot* be stubbed/verified: final/private/equals()/hashCode().
Mocking methods declared on non-public parent classes is not supported.
at org.mockito.internal.runners.DefaultInternalRunner$1$1.testFinished(DefaultInternalRunner.java:58)
at org.junit.runner.notification.SynchronizedRunListener.testFinished(SynchronizedRunListener.java:56)
at org.junit.runner.notification.RunNotifier$7.notifyListener(RunNotifier.java:190)
at org.junit.runner.notification.RunNotifier$SafeNotifier.run(RunNotifier.java:72)
at org.junit.runner.notification.RunNotifier.fireTestFinished(RunNotifier.java:187)
at org.junit.internal.runners.model.EachTestNotifier.fireTestFinished(EachTestNotifier.java:38)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:331)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:68)
at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:74)
at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:161)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)