Home > other >  In Kotlin, how can one unit test that a data class, sealed class, or class field are not changed?
In Kotlin, how can one unit test that a data class, sealed class, or class field are not changed?

Time:01-30

Basically we might have some data like so

open class RealmCart : RealmObject() {
    @PrimaryKey
    var _id: String = UUID.randomUUID().toString()
    var items: RealmList<RealmCartItem> = RealmList()
    var discountCode: String? = null
    var userId: String = ""
}

And we do not want people editing these by mistake. We have some failsafe like code owners, labels in the repo, but we also want to have a unit test that can also prevent a merge if the data is changed in any way (add, change, or remove data). Basically, we do not want any accidents, and people are not perfect.

What is the best way to go about such a thing?

CodePudding user response:

This is what I ended up doing:

I created an extension function for my data models

fun RealmObject.testDeclaredFields(): List<String> {
    val fields = this::class.java.fields.map { it.name }
    return this::class.java.declaredFields
        .map { it.name }
        .filterNot { fields.contains(it) }
        .sorted()
}

Basically this just gets the data model fields, excluding things like companion objects.

Then I was able to create a test simply like

class RealmMessageTest {

    @Test
    fun `RealmMessage fields match spec`() {
        val item = RealmMessage().testDeclaredFields()
        assertContentEquals(item, fieldSpec)
    }

    private val fieldSpec = listOf(
        "_id",
        "acknowledgeStatusValue",
        "body",
        "completed",
        "createdAt",
        "deliveryStatusValue",
        "from",
        "meta",
        "organizationId",
        "platforms",
        "threadId",
        "title"
    ).sorted()
}

Why do this? Sometimes when someone is making changes carelessly, they will not realize that they have added a field, changed a field, or removed an important field in a data model that is sync'd to the backend. This does not prevent the developer from changing it, but given that they need to now change it in two places, they will be more cognizant whether they need to make this change or not.

I noticed a lot of people questioned why you would need to do this. My answer is that, I work in a very large repo where newer developers edit this without a second thought. This is just to make them more cognizant of changes to these important models, before they break develop. There are code owners for the repo, but they may not always see these changes. It is just an extra precaution.

CodePudding user response:

How about using a mechanism like githooks to prevent the editing of certain files from being committed?
I'm not familiar with githooks, so I can't show you exactly how to do it, but I think it would be good to prevent commits and inform the developer of the situation with an error message.

  •  Tags:  
  • Related