使用协程测试 Retrofit
Testing Retrofit with coroutines
如何使用 Retrofit
和 Coroutines
正确测试 Http
request/response?
我正在使用最新的 Retrofit
版本:2.6.0
支持 suspend
函数。
编辑
我还提供了一些代码以便于实施:
ApiInterface
@GET
suspend fun getCountriesListAsync(@Url url: String): Response<ArrayList<Country>>
一些存储库
suspend fun makeCountryApiCallAsync(): Response<ArrayList<Country>> =
treasureApi.getCountriesListAsync(COUNTRIES_API_URL)
ViewModel
上的实施:
private suspend fun makeCountriesApiCall() {
withContext(Dispatchers.Main) {
switchProgressBarOn()
}
try {
val countriesListResponse = setupRepository.makeCountryApiCallAsync()
if (countriesListResponse.isSuccessful) {
withContext(Dispatchers.Main) {
switchProgressOff()
countriesList.value = countriesListResponse.body()
}
} else {
withContext(Dispatchers.Main) {
showErrorLayout()
}
}
} catch (e: Exception) {
e.printStackTrace()
withContext(Dispatchers.Main) {
showErrorLayout()
}
}
}
我想你是在问如何测试协程?
无论你的逻辑在哪里,你都应该测试。正如我所见,您的存储库除了 Api 调用之外不包含任何逻辑。如果是这种情况,您无法针对实时数据进行测试,因为它不一致,但您可以使用 WireMock 或 Mockito 模拟一些结果并尝试使其通过您的逻辑。
有coroutine test support你可以看看
这是一个例子
协程测试必备(你可以不用但有这个更容易)
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.3.0-M1'
可选,我用来模拟我的通话结果
testImplementation 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.1.0'
以你给的例子
@ExperimentalCoroutinesApi
class ViewModelTest {
private val testDispatcher = TestCoroutineDispatcher()
private val testScope = TestCoroutineScope(testDispatcher)
@Before
fun before() {
Dispatchers.setMain(testDispatcher)
}
@After
fun after() {
Dispatchers.resetMain()
testScope.cleanupTestCoroutines()
}
@Test
fun testYourFunc() = testScope.runBlockingTest {
val mockRepo = mock<MyRepository> {
onBlocking { makeCountryApiCallAsync("") } doReturn Response.success(listOf())
}
val viewModel = TheViewModel(mockRepo)
val result = viewModel.makeCountriesApiCall() // Or however you can retrieve actual changes the repo made to viewmodel
// assert your case
}
}
如何使用 Retrofit
和 Coroutines
正确测试 Http
request/response?
我正在使用最新的 Retrofit
版本:2.6.0
支持 suspend
函数。
编辑
我还提供了一些代码以便于实施:
ApiInterface
@GET
suspend fun getCountriesListAsync(@Url url: String): Response<ArrayList<Country>>
一些存储库
suspend fun makeCountryApiCallAsync(): Response<ArrayList<Country>> =
treasureApi.getCountriesListAsync(COUNTRIES_API_URL)
ViewModel
上的实施:
private suspend fun makeCountriesApiCall() {
withContext(Dispatchers.Main) {
switchProgressBarOn()
}
try {
val countriesListResponse = setupRepository.makeCountryApiCallAsync()
if (countriesListResponse.isSuccessful) {
withContext(Dispatchers.Main) {
switchProgressOff()
countriesList.value = countriesListResponse.body()
}
} else {
withContext(Dispatchers.Main) {
showErrorLayout()
}
}
} catch (e: Exception) {
e.printStackTrace()
withContext(Dispatchers.Main) {
showErrorLayout()
}
}
}
我想你是在问如何测试协程?
无论你的逻辑在哪里,你都应该测试。正如我所见,您的存储库除了 Api 调用之外不包含任何逻辑。如果是这种情况,您无法针对实时数据进行测试,因为它不一致,但您可以使用 WireMock 或 Mockito 模拟一些结果并尝试使其通过您的逻辑。
有coroutine test support你可以看看
这是一个例子
协程测试必备(你可以不用但有这个更容易)
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.3.0-M1'
可选,我用来模拟我的通话结果
testImplementation 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.1.0'
以你给的例子
@ExperimentalCoroutinesApi
class ViewModelTest {
private val testDispatcher = TestCoroutineDispatcher()
private val testScope = TestCoroutineScope(testDispatcher)
@Before
fun before() {
Dispatchers.setMain(testDispatcher)
}
@After
fun after() {
Dispatchers.resetMain()
testScope.cleanupTestCoroutines()
}
@Test
fun testYourFunc() = testScope.runBlockingTest {
val mockRepo = mock<MyRepository> {
onBlocking { makeCountryApiCallAsync("") } doReturn Response.success(listOf())
}
val viewModel = TheViewModel(mockRepo)
val result = viewModel.makeCountriesApiCall() // Or however you can retrieve actual changes the repo made to viewmodel
// assert your case
}
}