简体   繁体   中英

Check lists of objects for equality without order check in their List property

Preconditions: I am deserializing a complex JSON into data class. The destination class has a bit of a complex hierarchy.

I have a list of objects List. Where ServiceFeature is the following (it's in kotlin, but does not matter):

data class ServiceFeature(
    val flagValue: String?,
    val effectiveFlagValue: String?,
    val name: String?,
    val attributes: List<Attribute?>?
)

As you can see ServiceFeature has an "attributes" property which includes another List of "Attribute". The main point is that Attributes in list might be in any order. Is there a reliable way to compare two lists of ServiceFeatures without order check from List<Attribute?>

I am trying to find a solution with assertJ.

If order does not matter for your attributes and they are unique (ie may not have multiple attributes of the same type) you might change the structure into a Set<Attribute?> instead and just use the regular compare.

If you want to preserve order but compare (unique) attributes you may convert them to set when comparing, see Easiest way to convert a List to a Set in Java .

If order of elements doesn't matter, then you can use Set instead of List . Having said that, You can use containsExactlyInAnyOrder() method provided by AssertJ. This method expects var-args as an argument, so in order to convert list to array we can use toTypedArray along with spread operator Eg


import org.junit.Test
import org.assertj.core.api.Assertions.*

data class ServiceFeature(
        val flagValue: String?,
        val effectiveFlagValue: String?,
        val name: String?,
        val attributes: List?
)

data class Attribute(val name: String?)

class SimpleTest {
    @Test
    fun test() {
        val list1 = listOf(ServiceFeature("flagA", "effectiveFlagA", "foo", listOf(Attribute("a"), Attribute("b"))))
        val list2 = listOf(ServiceFeature("flagA", "effectiveFlagA", "foo", listOf(Attribute("b"), Attribute("a"))))
        list1.zip(list2).forEach {
            assertThat(it.first.name).isEqualTo(it.second.name)
            assertThat(it.first.effectiveFlagValue).isEqualTo(it.second.effectiveFlagValue)
            assertThat(it.first.name).isEqualTo(it.second.name)
            val toTypedArray = it.second.attributes!!.toTypedArray() // null-check as per your need
            assertThat(it.first.attributes).containsExactlyInAnyOrder(*toTypedArray)
        }

    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM