前提条件:我将复杂的json反序列化为数据类。目标类有一个复杂的层次结构。
我有一个对象List列表。其中ServiceFeature是以下(它在kotlin中,但无关紧要):
data class ServiceFeature(
val flagValue: String?,
val effectiveFlagValue: String?,
val name: String?,
val attributes: List<Attribute?>?
)
正如您所看到的,ServiceFeature具有“属性”属性,该属性包含另一个“属性”列表。重点是列表中的属性可以是任何顺序。 有没有一种可靠的方法来比较两个ServiceFeatures列表,而无需从List
进行订单检查我正在尝试使用assertJ找到解决方案。
提前谢谢。
答案 0 :(得分:2)
如果顺序对您的属性无关紧要并且它们是唯一的(即可能没有相同类型的多个属性),您可以将结构更改为Set<Attribute?>
而只使用常规比较。
如果您想保留订单但比较(唯一)属性,您可以在比较时将它们转换为设置,请参阅Easiest way to convert a List to a Set in Java。
答案 1 :(得分:2)
如果元素的顺序无关紧要,那么您可以使用Set
代替List
。话虽如此,您可以使用AssertJ提供的containsExactlyInAnyOrder()方法。此方法需要var-args作为参数,因此为了将列表转换为数组,我们可以使用toTypedArray和spread operator例如。
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)
}
}
}