Тестирование с сетью. Разные ответы
В статье Простой тест для работы с сетью мы узнали как сделать самый простой веб сервер для тестирования. В этой статье мы его немного расширим и сделаем более гибким для разных запросов.
Сначала мы добавим в наш Api еще один вызов
interface ApiTest {
@GET("characters")
fun loadCharacters(): Call<List<CharacterResponse>>
@GET("episodes")
fun loadEpisodes(): Call<List<EpisodeResponse>>
}
data class EpisodeResponse(
@SerializedName("name") val name: String,
@SerializedName("date") val date: Date
)
В теории практически любой запрос в сеть возвращает какой-то ответ. Не будем рассматривать специфические случаи и представим, что в идеале нам будет возвращаться какой-то json
. Можно эти ответы хранить в виде переменных в файле с имплементацией MockWebServer
, но это не совсем правильно. Лучше их хранить в виде json
файлов, которые будут доступны только для тестов.
Расширим создание вебсервера:
internal fun createMockServer(listener: DispatchListener): MockWebServer {
val mockWebServer = MockWebServer()
mockWebServer.start(8080)
mockWebServer.dispatcher = object : Dispatcher() {
override fun dispatch(request: RecordedRequest): MockResponse {
val responseFile = buildString {
append(listener.convertUrlToLocalFile(request.path.orEmpty(), method = request.method))
append(".json")
}
val content = getMockResponse(responseFile)
return MockResponse().setResponseCode(200).setBody(content)
}
}
return mockWebServer
}
fun interface DispatchListener {
fun convertUrlToLocalFile(path: String, method: String?): String?
}
Пара функций для чтения контента из файла
fun getFileAsString(filePath: String): String {
return Thread.currentThread().contextClassLoader?.getResourceAsStream(filePath)?.bufferedReader().use { it?.readText() }.orEmpty()
}
fun getMockResponse(fileName: String) = getFileAsString(fileName)
Определимся, что файлы с ответами сервера у нас лежат в директории moduleName/src/test/resources
где по умолчанию moduleName=app
Последнее, что осталось сделать - указать нашему вебсерверу как обрабатывать запросы и содержимое какого файла возвращать.
@Before
fun setup() {
mockWebServer = createMockServer { path, method ->
when (path) {
"/characters" -> "response_characters"
"/episodes" -> "response_episodes"
else -> null
}
}
api = createApi<ApiTest>(mockWebServer)
}
В следующем посте мы будем работать с Api не напрямую, а через репозиторий