【问题标题】:Kotlin data class Jackson serialization/deserialization same object failedKotlin 数据类 Jackson 序列化/反序列化相同对象失败
【发布时间】:2020-08-12 08:30:22
【问题描述】:

目前我正在开发一个 Kotlin 项目,我们使用 Jackson 对我们的 data classes 进行序列化/反序列化。我开始编写一些单元测试,并介绍了当创建data class 的实例之后对其进行序列化而不是反序列化时,我收到了不同的对象。

我的意思是:

我的数据类

data class TestEvent(
    @JsonProperty("stringProperty")
    val stringProperty: String,

    @JsonProperty("intProperty") 
    val intProperty: Int? = null,

    @JsonProperty("int32Property") 
    val int32Property: Int? = null,

    @JsonProperty("int64Property") 
    val int64Property: Long? = null,

    @JsonProperty("floatProperty") 
    val floatProperty: Float? = null,

    @JsonProperty("doubleProperty") 
    val doubleProperty: Double? = null,

    @JsonProperty("byteProperty") 
    val byteProperty: ByteArray? = null,

    @JsonProperty("booleanProperty") 
    val booleanProperty: Boolean? = null,

    @JsonProperty("dateProperty") 
    val dateProperty: java.time.LocalDate? = null,

    @JsonProperty("dateTimeProperty") 
    val dateTimeProperty: java.time.OffsetDateTime? = null,

    @JsonProperty("uuidProperty") 
    val uuidProperty: java.util.UUID? = null
)

测试

class SerializationTest {

    private lateinit var mapper: ObjectMapper

    @Before
    fun setup() {
        mapper = ObjectMapper()
                .registerModule(KotlinModule())
                .registerModule(JavaTimeModule())
                .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
                .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
                .setSerializationInclusion(JsonInclude.Include.NON_NULL)
    }

    @Test
    fun testJacкsonDeserialize() {
        val testEvent = createTestEvent()
        val serializedEvent = mapper.writeValueAsString(testEvent)
        val deserializedEvent = mapper.readValue(serializedEvent, TestEvent::class.java)
        Assert.assertEquals(testEvent, deserializedEvent)
    }

    fun createTestEvent() = TestEvent(
            stringProperty = "Test event",
            intProperty = 12,
            int32Property = 34,
            int64Property = 54L,
            floatProperty = 12.0f,
            doubleProperty = 566.0,
            byteProperty = byteArrayOf(3, 5, 7, 9),
            booleanProperty = false,
            dateProperty = LocalDate.of(2020, 1, 20),
            dateTimeProperty = OffsetDateTime.of(LocalDate.of(2020, 1, 20), LocalTime.of(10, 0, 10), ZoneOffset.UTC),
            uuidProperty = UUID.fromString("2dd41a88-bf52-42ba-8ab9-d202139582ee")
    )
}

运行测试后收到此异常:

java.lang.AssertionError: expected: 
TestEvent<TestEvent(stringProperty=Test event, intProperty=12, int32Property=34, int64Property=54, floatProperty=12.0, doubleProperty=566.0, byteProperty=[3, 5, 7, 9], booleanProperty=false, dateProperty=2020-01-20, dateTimeProperty=2020-01-20T10:00:10Z, uuidProperty=2dd41a88-bf52-42ba-8ab9-d202139582ee)> but was: 
TestEvent<TestEvent(stringProperty=Test event, intProperty=12, int32Property=34, int64Property=54, floatProperty=12.0, doubleProperty=566.0, byteProperty=[3, 5, 7, 9], booleanProperty=false, dateProperty=2020-01-20, dateTimeProperty=2020-01-20T10:00:10Z, uuidProperty=2dd41a88-bf52-42ba-8ab9-d202139582ee)>
Expected :TestEvent<TestEvent(stringProperty=Test event, intProperty=12, int32Property=34, int64Property=54, floatProperty=12.0, doubleProperty=566.0, byteProperty=[3, 5, 7, 9], booleanProperty=false, dateProperty=2020-01-20, dateTimeProperty=2020-01-20T10:00:10Z, uuidProperty=2dd41a88-bf52-42ba-8ab9-d202139582ee)> 
Actual   :TestEvent<TestEvent(stringProperty=Test event, intProperty=12, int32Property=34, int64Property=54, floatProperty=12.0, doubleProperty=566.0, byteProperty=[3, 5, 7, 9], booleanProperty=false, dateProperty=2020-01-20, dateTimeProperty=2020-01-20T10:00:10Z, uuidProperty=2dd41a88-bf52-42ba-8ab9-d202139582ee)>

您如何看到两个对象是相同的,但是测试失败了,我认为唯一不同的是在 IDE 的比较视图中,它在对象通用标记后显示了一些添加的空白空间,附上屏幕截图:

我错过了什么吗?你能在这里给个建议吗?

【问题讨论】:

    标签: android kotlin serialization jackson deserialization


    【解决方案1】:

    经过一天的思考和研究,我发现这篇文章拯救了我:

    https://medium.com/asos-techblog/what-you-didnt-know-about-arrays-in-kotlin-d3b20337e4

    最重要的是:

    Kotlin 比较数组的引用,而不是内容。在 Java 类中,Arrays.equals() 用于检查内容,而不是引用。由于我们在这里创建了两个数组,所以它们有不同的引用。

    因此,如果您的数据类包含 Array,您必须覆盖 equals 或使用 List 更改它,否则 equals 将无法正常工作。

    希望这能为某人节省至少一天的时间:)

    【讨论】:

      猜你喜欢
      • 2018-12-26
      • 1970-01-01
      • 1970-01-01
      • 2011-06-14
      • 1970-01-01
      • 1970-01-01
      • 2019-06-01
      • 1970-01-01
      • 2017-11-06
      相关资源
      最近更新 更多