首页 > 解决方案 > 使用协程测试改造

问题描述

您如何正确地使用and测试Http请求/响应?RetrofitCoroutines

我正在使用最新Retrofit版本:2.6.0它支持suspend功能。

编辑

我还提供了一些代码以便于实现:

API接口

@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()
            }
        }
    }

标签: androidretrofit2android-testingkotlin-coroutines

解决方案


我想你是在问如何测试协程?

无论您的逻辑在哪里,您都应该进行测试。正如我所见,您的存储库不包含 Api 调用之外的任何逻辑。如果是这种情况,您无法针对实时数据进行测试,因为它不一致,但您可以使用 WireMock 或 Mockito 模拟某些结果并尝试使其通过您的逻辑。

协程测试支持,你可以看看它。

这是一个例子

协程测试必不可少(你可以不这样做,但这样做会容易得多)

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
    }
}

推荐阅读