如何使用mockito在我的retrofit2演示器上实现单元测试



我想通过在代码上使用mockito依赖项来进行单元测试。它总是失败,因为view.processMatchData(data(和view.hideLoading((在这个演示程序代码的闭包部分,所以单元测试不会检测到它们。求你了,有人帮我解决这个问题。

open class MatchSearchPresenter(
private val view: MatchSearchView,
private val apiService: ApiService,
private val cari : String
) {
fun searchMatch() {
view.showLoading()
apiService.loadSearchMatch(cari).enqueue(object : Callback<MatchSearchResponseModel> {
override fun onResponse(call: Call<MatchSearchResponseModel>, response: Response<MatchSearchResponseModel>)
{
if (response.isSuccessful) {
val data = response.body()!!
view.processMatchData(data)
}
view.hideLoading()
}
override fun onFailure(call: Call<MatchSearchResponseModel>, error: Throwable)
{
Log.e("Error", error.message)
view.hideLoading()
}
})
}
}

这是我的单元测试:

class MatchSearchPresenterTest {
@Mock
private lateinit var view: MatchSearchView
@Mock
private lateinit var apiService: ApiService
@Mock
private lateinit var teamPresenter: MatchSearchPresenter
@Mock
private lateinit var call: Call<MatchSearchResponseModel>
@Mock
private lateinit var something: Callback<MatchSearchResponseModel>

@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
val kata = "Man United"
teamPresenter = MatchSearchPresenter(view, apiService, kata )
}
@Test
fun searchMatch() {
val teamId = "Man United"
val teams: MutableList<PrevMatchData> = mutableListOf()
val data = MatchSearchResponseModel(teams)
teamPresenter.searchMatch()
argumentCaptor<MatchSearchView>().apply {
Mockito.verify(apiService.loadSearchMatch(teamId).enqueue(something))
firstValue.processMatchData(data)
firstValue.hideLoading()
}
Mockito.verify(view).showLoading()
Mockito.verify(view).processMatchData(data)
Mockito.verify(view).hideLoading()
}
}

但通过显示这样的消息是不起作用的:

java.lang.NullPointerException
at com.example.footballleaguecataloguefourth.ui_bottom_navigation.schedule.match_search.MatchSearchPresenter.searchMatch(MatchSearchPresenter.kt:19)
at com.example.footballleaguecataloguefourth.ui_bottom_navigation.schedule.match_search.MatchSearchPresenterTest.searchMatch(MatchSearchPresenterTest.kt:41)

我认为您想要的是让ApiService返回的调用在入队后立即调用正确的方法。

要做到这一点,你可以使用Mockito的thenAnswer-这里有一个例子。在你的情况下,你可以试试这个:

Mockito.`when`(call.enqueue(Mockito.any())).thenAnswer {
(it.getArgument(0) as Callback<MatchSearchResponseModel>).onResponse(
call,
Response.success(MatchSearchResponseModel(/*whatever is needed to build this object*/))
)
}

在这里,您要确保一旦使用任何参数调用call.enqueue,它就会立即调用具有成功响应的onResponse方法。您可以对错误执行类似的操作,也可以调用onFailure

您需要做的最后一件事是确保您的api服务返回配置的模拟call:

Mockito.`when`(apiService.loadSearchMatch(kata)).thenReturn(call)

我会把这个放在每次测试中。因此,在调用演示者方法之前,我会这样配置mock。

现在,调用teamPresenter.searchMatch(),应该调用apiService.loadSearchMatch(cari),它将返回模拟调用,该调用一旦入队,将调用传递的回调的onResponse方法。

最后,正如您可能已经注意到的,when实际上是用backticks编写的。这是因为它是一个需要转义的kotlin关键字。不仅因为这个原因,还有更多的原因,你可以考虑使用Mockito Kotlin,这是一个极好的Kotlin库,它包装了Mockito,让生活变得更轻松。

最新更新