Skip to content

Gson behaviour is different in Unit test and in actual build #2713

@The-Pascal

Description

@The-Pascal

Gson version

2.11.0

Java / Android version

JDK 17
Sample of my build.gradle

android {
    namespace = "com.test.package"
    compileSdk = Config.compileSdk

    defaultConfig {
        minSdk = Config.minSdk
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    compileOptions {
        sourceCompatibility = Config.sourceCompatibility
        targetCompatibility = Config.targetCompatibility
    }

    kotlinOptions {
        jvmTarget = "1.8"
    }
}

dependencies {
    testImplementation("junit:junit:4.13.2")
    testImplementation("androidx.test:core:1.6.1")

    implementation("com.google.code.gson:gson:2.11.0")
}

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.

class JsonConverterTest {

    data class Person(
        val name: String,
        val age: Int,
        val isVerified: Boolean = false,
        val margin: Float = 1.0f,
        val gains: Double = 2.0,
        val profit: Double? = 4.0,
        val friends: 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugkotlinIssues concerning the use of Gson with Kotlinneeds-info

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions