Intereting Posts
Котлинский андроид Расширения в Котлине Мне нужен способ динамически, progammaticaly изменить фон для ImageView в представлении Recycler Живые данные MPAndroidChart не отображаются без начальных границ Объединение обязательных и произвольных необязательных аргументов конструктора с Groovy Обменный код между модульными испытаниями и контрольно-измерительными тестами при использовании котлина Инициализация val путем деструктуризации в Котлине Как включить обработчик, обработанный обработчиком аннотации, для проверки класса пути в Java / Kotlin Большое время компиляции кода Kotlin в IntelliJ Проблемы с подключением API-интерфейсов доступа к приложениям с поддержкой – Android Как подавить проверку орфографии на константе строки в Android Kotlin? Запросы Firebase никогда не заканчиваются на Android smart cast невозможно, потому что экземпляр является изменяемым свойством Циркулярные ссылки с vals в Котлине Ссылка на вложенную собственность Котлин

Разбор json со сломанным удаленным API

Вот мой модельный класс

data class Article( val id: Int? = 0, val is_local: Boolean? = false, val comments: List<Comment?>? = listOf())

и вот json

  { "id": 33, "is_local": "true", "comments": [ { "url": "aaa" }, { "url": "bbb" }, { "url": "ccc" ) ] } 

Я использую этот настраиваемый адаптер для возврата значения по умолчанию в случае ошибки синтаксического анализа, как в моем случае is_local field

 class DefaultOnDataMismatchAdapter<T> private constructor(private val delegate: JsonAdapter<T>, private val defaultValue: T?) : JsonAdapter<T>() { @Throws(IOException::class) override fun fromJson(reader: JsonReader): T? = try { delegate.fromJsonValue(reader.readJsonValue()) } catch (e: Exception) { println("Wrongful content - could not parse delegate " + delegate.toString()) defaultValue } @Throws(IOException::class) override fun toJson(writer: JsonWriter, value: T?) { delegate.toJson(writer, value) } companion object { @JvmStatic fun <T> newFactory(type: Class<T>, defaultValue: T?): JsonAdapter.Factory { return object : JsonAdapter.Factory { override fun create(requestedType: Type, annotations: Set<Annotation>, moshi: Moshi): JsonAdapter<*>? { if (type != requestedType) { return null } val delegate = moshi.nextAdapter<T>(this, type, annotations) return DefaultOnDataMismatchAdapter(delegate, defaultValue) } } } } } 

и мой тест терпит неудачу, и логическое значение не является ложным, я добавил указанный выше адаптер в moshi

 @Before fun createService() { val moshi = Moshi.Builder() .add(DefaultOnDataMismatchAdapter .newFactory(Boolean::class.java,false)) .add(KotlinJsonAdapterFactory()) .build() val retrofit = Retrofit.Builder() .baseUrl(mockWebServer.url("/")) .addConverterFactory(MoshiConverterFactory.create(moshi)) .build() service = retrofit.create(ApiStores::class.java) } @Test fun getBooleanParsingError() { enqueueResponse(case1) val article = service.getArticle().execute() assert(article.body()!!).isNotNull() assert(article.body()!!.is_local).isEqualTo(false) // test fail here } 

но когда я изменяю тип данных поля is_local в классе модели, чтобы он не был нулевым, он работает

Проблема в том, что типы kotlin.Boolean и kotlin.Boolean? соответствуют двум различным типам Java:

  • kotlin.Booleanboolean примитивный тип Java
  • kotlin.Boolean? это java.lang.Boolean Тип Java

В вашем тесте вы создали адаптер для kotlin.Boolean (т. kotlin.Boolean boolean тип Java), а в вашей модели данных у вас есть kotlin.Boolean? (т. е. тип java.lang.Boolean ). По этой причине, когда метод create(...) Factory вызывается, вы находитесь в ситуации, когда type != requestedType KotlinJsonAdapter , поэтому ваш адаптер не создан и вместо этого используется KotlinJsonAdapter . На этом этапе, поскольку is_local поле Json не является логическим (но строкой), Моши должен поднять Исключение.

Если вы измените модель данных или ваш адаптер на использование одного и того же типа, вы находитесь в ситуации, когда type == requestedType , поэтому ваш адаптер создается, исключение генерируется, как и раньше, но вы добавили блок catch который возвращает значение по умолчанию ,