Search code examples
unit-testingkotlinassertionkotlin-multiplatformkotlin-js

Is there a way to make equals (==) check on kotlin.js.Date object work?


I would like to ask for some help/suggestions on an issue we're facing when trying to unit test platform specific Date classes in our Kotlin Multiplatform project.

Our Kotlin Multiplatform library targets; JVM, Native & JavaScript and is using the platform specific Date classes:

  • java.util.Date (JVM)
  • platform.Foundation.NSDate (Native)
  • kotlin.js.Date (JS)

Which are exposed via an expected/actual Date class and used in public domain classes in the common package. For example:

public data class Event {
    val id: String,
    val start: Date
}

Long story short; when unit testing we found that assertEquals works for JVM & Native, but fails for JavaScript. For example:

import kotlin.js.Date
import kotlin.test.Test
import kotlin.test.assertEquals

class DateEqualsTest {

    @Test
    // Fails!
    fun dateEquals() {
        val first = Date(1_630_399_506_000)
        val second = Date(1_630_399_506_000)
        assertEquals(first, second)
    }

    @Test
    // Succeeds
    fun timestampEquals() {
        val first = Date(1_630_399_506_000)
        val second = Date(1_630_399_506_000)
        assertEquals(first.getTime(), second.getTime())
    }
}

The assertEquals fails for JS due to (I guess) a missing equals() operator in the kotlin.js.Date class.

Any suggestions on how to make the assertEquals work on all platforms given our use case? I can imagine a workaround could be to introduce a DateWrapper class that wraps the Date class and implement the equals() manually... but that would require use to refactor our public API and not sure if that is the best way to go. So any help/ suggestion is super welcome. Many thanks!


Solution

  • assertEquals will not work because there is no way you can add equals method to kotlin.js.Date class - it is external function exposing Date API and all comparisons will be done the same way as would be done in JS

    Just read this article:

    To make it work you should use getTime() or provide wrapper class as you wrote or create overloaded assertEquals method in your test class or another util file

    fun assertEquals(d1: Date, d2: Date) {
        kotlin.test.assertEquals(d1.getTime(), d2.getTime())
    }
    

    still then you need to take care about imports