我成功地进行了一些异步函数测试,只有一个回调接口作为mockito-kotlin库的参数,但当我尝试用另一个参数(如String或Integer)测试相同的函数时,我收到错误:
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
无效使用参数匹配器!
预期2个匹配者,1个记录:
- > at com.example.presentation.presenter.MyCollectionPresenterTest.getComicListByHeroOK(MyCollectionPresenterTest.kt:97)
如果匹配器与原始值结合使用,则可能发生此异常:
//不正确的:
someMethod(anyObject(),“raw String”);
使用匹配器时,所有参数都必须由匹配器提供。
例如:
//正确的:
someMethod(anyObject(),eq(“by matcher”));
有关更多信息,请参阅Matchers类的javadoc。
我确定我正在使用any()正确地模拟回调接口,但我不知道我是否正确地模拟了整数参数。我尝试使用any()
,anyInt()
,eq(1)
和any() as Int
但始终存在相同的错误。
以下是我要测试的课程:
@PerFragment
class MyCollectionPresenter @Inject constructor(private val useCase: GetComicListByHeroUseCase) {
@Inject
lateinit var view: MyCollectionView
lateinit var models: List<ComicModel>
fun getComicListByHero(heroId: Int) {
useCase.execute(heroId, object : HeroUseCase.GetComicListByHeroCallback {
override fun onComicListReceived(comicList: List<Comic>) {
models = ComicModelMapper.toModel(comicList)
view.setItems(models)
}
override fun onError() {
view.showMessage()
}
})
}
}
这是测试类:
class MyCollectionPresenterTest : UnitTest() {
private lateinit var presenter: MyCollectionPresenter
@Mock
private lateinit var useCase: GetComicListByHeroUseCase
@Mock
private lateinit var view: MyCollectionView
@Before
fun setUp() {
presenter = MyCollectionPresenter(useCase)
initializeView()
}
@Test
fun getComicListByHeroOK() {
setupGetComicsCallbackOK()
presenter.getComicListByHero(any())
verify(presenter.view).setItems(emptyList())
}
@Test
fun getComicListByHeroError() {
setupGetComicsCallbackError()
presenter.getComicListByHero(any())
verify(presenter.view).showMessage()
}
private fun initializeView() {
presenter.view = view
}
private fun setupGetComicsCallbackError() {
doAnswer {
val callback = it.arguments[0] as HeroUseCase.GetComicListByHeroCallback
callback.onError()
null
}.`when`(useCase).execute(any(), any())
}
private fun setupGetComicsCallbackOK() {
doAnswer {
val callback = it.arguments[0] as HeroUseCase.GetComicListByHeroCallback
callback.onComicListReceived(emptyList())
null
}.`when`(useCase).execute(any(), any())
}
}
这是基本单元测试类:
@RunWith(MockitoJUnitRunner::class)
abstract class UnitTest {
@Suppress("LeakingThis")
@Rule
@JvmField
val injectMocks = InjectMocksRule.create(this@UnitTest)
}
这是一个注入模拟规则的类:
class InjectMocksRule {
companion object {
fun create(testClass: Any) = TestRule { statement, _ ->
MockitoAnnotations.initMocks(testClass)
statement
}
}
}
非常感谢你的帮助,请原谅我的英语。
问候!
更新:我找到了解决方案并发布了答案。
答案 0 :(得分:0)
最后,我知道我做错了什么。首先,it.argument[1]
因为回调是我想要模拟答案的函数的第二个参数。
另一件事是我正在模拟我要测试presenter.getComicListByHero(1)
的函数的参数。
以下是修订后的代码:
@Test
fun getComicListByHeroError() {
setupGetComicsCallbackError()
presenter.getComicListByHero(1)
verify(presenter.view).showMessage()
}
private fun setupGetComicsCallbackError() {
doAnswer {
val callback = it.arguments[1] as HeroUseCase.GetComicListByHeroCallback
callback.onError()
null
}.`when`(useCase).execute(ArgumentMatchers.anyInt(), any())
}
非常感谢@voghDev的帮助