Тестирование Retrofit с сопрограммами - PullRequest
1 голос
/ 11 июня 2019

Как правильно проверить Http запрос / ответ с Retrofit и Coroutines?

Я использую последнюю версию 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()
            }
        }
    }

1 Ответ

1 голос
/ 12 июня 2019

Полагаю, вы спрашиваете, как тестировать сопрограммы?

Вам следует проверять всю свою логику.Как я вижу, ваш репозиторий не содержит никакой логики, кроме вызова 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
    }
}
...