You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While using Gson in unit tests, when converting json string to data class, if json string doesn't contains some fields, then it falls to default of data type like for nullables it falls to null.
However, on actual builds, it's taking default values when json string doesn't contains some fields.
Expected behavior
Both actual app behaviour and unit tests behaviour for Gson should be same.
Actual behavior
In actual app if fields are missing, then it takes data class default values.
In unit tests, if fields are missing, then it takes data type default (like for int - 0, for nullables - null, etc)
Reproduction steps
Run this unit test using android studio.
classJsonConverterTest {
data classPerson(
valname:String,
valage:Int,
valisVerified:Boolean = false,
valmargin:Float = 1.0f,
valgains:Double = 2.0,
valprofit:Double? = 4.0,
valfriends:List<String>? = listOf()
)
@Test
fun`test gson serialization`() {
val jsonString ="""{"name":"John","age":30,"isVerified":true,"margin":1.0,"gains":5.0}"""val actual =Gson().fromJson(jsonString, Person::class.java)
val expected =Person("John", 30, true, 1.0f, 5.0, 4.0, listOf())
assertWithMessage("Failed for case: $jsonString").that(actual).isEqualTo(expected)
}
}
Output after running above unit test
Failed for case: {"name":"John","age":30,"isVerified":true,"margin":1.0,"gains":5.0}
expected: Person(name=John, age=30, isVerified=true, margin=1.0, gains=5.0, profit=4.0, friends=[])
but was : Person(name=John, age=30, isVerified=true, margin=1.0, gains=5.0, profit=null, friends=null)
Expected output
Test should get passed.
PS: let me know if I missed something
The text was updated successfully, but these errors were encountered:
The behavior of the unit test is likely caused by Gson's limited support for Kotlin (see also the Gson README and #2666). Gson does not consider default values for constructor and function arguments, and because your class does not have a no-args constructor, Gson will fall back to using Unsafe to create the instance, which does not invoke any constructor. If you use GsonBuilder.disableJdkUnsafe(), it will probably fail, indicating that it previously relied on Unsafe.
Not sure why it works as expected in release mode. Maybe the code shrinker R8 is rewriting the code in a way which causes the class to have a no-args constructor. Out of curiosity, if you disable R8, does the release build then behave in the same (unexpected) way as the unit test?
We already have other GitHub issues for not well supported Kotlin features, see the
kotlinIssues concerning the use of Gson with Kotlin
label and particularly #1657. So this issue here is probably a duplicate.
Gson version
2.11.0
Java / Android version
JDK 17
Sample of my
build.gradle
Description
While using Gson in unit tests, when converting json string to data class, if json string doesn't contains some fields, then it falls to default of data type like for nullables it falls to null.
However, on actual builds, it's taking default values when json string doesn't contains some fields.
Expected behavior
Both actual app behaviour and unit tests behaviour for Gson should be same.
Actual behavior
In actual app if fields are missing, then it takes data class default values.
In unit tests, if fields are missing, then it takes data type default (like for int - 0, for nullables - null, etc)
Reproduction steps
Run this unit test using android studio.
Output after running above unit test
Expected output
Test should get passed.
PS: let me know if I missed something
The text was updated successfully, but these errors were encountered: